为啥在附加熊猫数据框时列顺序会发生变化?

Posted

技术标签:

【中文标题】为啥在附加熊猫数据框时列顺序会发生变化?【英文标题】:Why the column order is changing while appending pandas dataframes?为什么在附加熊猫数据框时列顺序会发生变化? 【发布时间】:2016-02-21 05:10:23 【问题描述】:

我想使用 Python pandas 附加(合并)文件夹中的所有 csv 文件。

例如:说文件夹有两个csv文件test1.csvtest2.csv如下:

A_Id    P_Id    CN1         CN2         CN3
AAA     111     702         709         740
BBB     222     1727        1734        1778

A_Id    P_Id    CN1         CN2         CN3
CCC     333     710        750          750
DDD     444     180        734          778

所以我写的python脚本如下:

#!/usr/bin/python
import pandas as pd
import glob

all_data = pd.DataFrame()
for f in glob.glob("testfolder/*.csv"):
    df = pd.read_csv(f)
    all_data = all_data.append(df)

all_data.to_csv('testfolder/combined.csv')

虽然combined.csv 似乎有所有附加的行,但它看起来如下:

      CN1       CN2         CN3    A_Id    P_Id
  0   710      750         750     CCC     333
  1   180       734         778     DDD     444     
  0   702       709         740     AAA     111
  1  1727       1734        1778    BBB     222

它应该看起来像这样:

A_ID   P_Id   CN1    CN2    CN2
AAA    111    702    709    740
BBB    222    1727   1734   1778
CCC    333    110    356    123
DDD    444    220    256    223
为什么前两列移到最后? 为什么附加在第一行而不是最后一行?

我错过了什么?以及如何在第一列中获取 0 和 1?

P.S:由于这些是大型 csv 文件,我想到了使用 pandas。

【问题讨论】:

熊猫使用什么版本的?因为它在 0.17.0 中运行良好。 我认为问题出在 csv 格式上 - 在行后尝试 df = pd.read_csv(f) 添加 print df.head() 进行检查。 我认为您将输出读取为输入glob.glob("testfolder/*.csv"):,因为输出写入输入目录:all_data.to_csv('testfolder/combined.csv'),您必须将目录更改为all_data.to_csv('out/combined.csv') 你可以通过添加参数index=Falseall_data.to_csv('out/combined.csv', index=False)来摆脱01 您可以按文件名对输入文件进行排序:for f in sorted(glob.glob("testfolder/*.csv")):。这将在 test2.csv 之前读取 test1.csv,并确保行的顺序正确... 【参考方案1】:

试试这个.....

all_data = all_data.append(df)[df.columns.tolist()]

【讨论】:

虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。不鼓励仅使用代码回答。 这可能是需要提交的 Pandas 错误吗?我有同样的问题。 @kingmakerking 提出的问题是“为什么”。例如,如果 2 个数据框有不同的列,这将无济于事。我也可以看到与 pd.concat 相同的问题 如果all_data 的列多于df,这将省略df 中不存在的列。【参考方案2】:

从 0.23.0 版本开始,您可以阻止 append() 方法对最终附加的 DataFrame 进行排序。在你的情况下:

all_data = all_data.append(df, sort=False)

【讨论】:

这现在也适用于 concat。 df = pd.concat([df1, df2], sort=False) 这对我不起作用。这对其他人有用吗? @msarafzadeh:它在 pandas 0.25.3 中运行良好。当您报告与版本相关的问题时,请始终说明您的版本号。你使用了来自 git 的 pandas-dev 流,还是一个版本(哪个?) 从 Pandas 开始,v1.0sort=False 是默认值。不过,这个问题似乎还是会出现……【参考方案3】:

我有同样的问题,而且很痛苦。在将源数据帧附加到最终数据帧后,我设法通过根据源数据帧重新组织列来解决它。它看起来像这样:

#!/usr/bin/python
import pandas as pd
import glob

all_data = pd.DataFrame()
for f in glob.glob("testfolder/*.csv"):
    df = pd.read_csv(f)
    all_data = all_data.append(df)
    all_data = all_data[df.columns]

all_data.to_csv('testfolder/combined.csv') 

由于您的问题是近两年前的问题,因此我发布的解决方案对我也适用,其他人也将面临类似问题。

【讨论】:

【参考方案4】:

你可以使用reindex改成原来的顺序:

all_data = all_data.append(df)
all_data = all_data.reindex(df.columns, axis=1)

我在这里看到了这个(更多细节在链接中):https://github.com/pandas-dev/pandas/issues/4588#issuecomment-44421883

【讨论】:

【参考方案5】:

我调整了如下代码。在线评论。

#!/usr/bin/python
import pandas as pd
import glob

# Grab all the csv files in the folder to a list.
fileList = glob.glob('input_folder/*.csv')

#Initialize an empty dataframe to grab the csv content.
all_data = pd.DataFrame()

#Initialize an empty list to grab the dataframes.
dfList= []

for files in  fileList:
    df =  pd.read_csv(files, index_col = None, header= False)
    dfList.append(df)

#The frames will be in reverse order i.e last read file's content in the begining. So reverse it again
Reversed_dfList =  dfList[::-1]
CombinedFrame =  pd.concat(Reversed_dfList)

# The "Combined.csv" file will have combination of all the files.
CombinedFrame.to_csv('output_folder/Combined.csv', index=False)

【讨论】:

【参考方案6】:

请尝试:

df = df.append(pd.DataFrame(Added_rows).T)

【讨论】:

【参考方案7】:

all_data = all_data.append(df, ignore_index=True)

设置 ignore_index=True 以便顺序不会改变。 默认是False,所以你需要改变它。

【讨论】:

以上是关于为啥在附加熊猫数据框时列顺序会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在这个循环中倒计时顺序会发生变化?

为啥使用 ggplotly 时我的工具提示的顺序会发生变化?

如果我为我的表命名,为啥 SQL 查询顺序会发生变化? [关闭]

当我以下列方式修改熊猫数据框时会发生啥

熊猫追加和连接重新排序数据框?

熊猫在数据检索后改变列的顺序