副标题:让 Pandas 哑巴,不要再变得聪明了。

我有一个单列 Pandas 数据帧的列表(res),每个数据帧都包含相同类型的数字数据,但每个字段具有不同的列名。行索引没有意义。我想将它们放入一个非常长的单列数据帧中。

当我执行pd.concat(res)时,每个输入文件都会得到一列(以及加载和加载NaN单元格)。我已经尝试过为参数(*)设置各种值,但没有一个可以满足我的要求。

编辑:样本数据:

res = [
    pd.DataFrame({'A':[1,2,3]}),
    pd.DataFrame({'B':[9,8,7,6,5,4]}),
    pd.DataFrame({'C':[100,200,300,400]}),
]

我有一个丑陋的解决方案:复制每个数据框并为其指定新的列名称:
newList = []
for r in res:
  r.columns = ["same"]
  newList.append(r)
pd.concat( newList, ignore_index=True )

当然这不是最好的方法吗?

顺便说一句,pandas: concat data frame with different column name是相似的,但是我的问题甚至更简单,因为我不想维护索引。 (我也从N个单列数据帧的列表开始,而不是一个N列数据帧的列表。)

*:例如axis=0是默认行为。 axis=1给出错误。 join="inner"太傻了(我只得到索引)。 ignore_index=True对索引重新编号,但是我仍然有很多列,很多NaN。

更新空列表

当数据有一个空列表时,我遇到了问题(使用所有给定的解决方案),例如:
res = [
    pd.DataFrame({'A':[1,2,3]}),
    pd.DataFrame({'B':[9,8,7,6,5,4]}),
    pd.DataFrame({'C':[]}),
    pd.DataFrame({'D':[100,200,300,400]}),
]

诀窍是通过添加.astype('float64')来强制类型。例如。
pd.Series(np.concatenate([df.values.ravel().astype('float64') for df in res]))

或者:
pd.concat(res,axis=0).astype('float64').stack().reset_index(drop=True)

最佳答案

我将使用列表理解为:

import pandas as pd
res = [
    pd.DataFrame({'A':[1,2,3]}),
    pd.DataFrame({'B':[9,8,7,6,5,4]}),
    pd.DataFrame({'C':[100,200,300,400]}),
]


x = []
[x.extend(df.values.tolist()) for df in res]
pd.DataFrame(x)

Out[49]:
      0
0     1
1     2
2     3
3     9
4     8
5     7
6     6
7     5
8     4
9   100
10  200
11  300
12  400

我为您测试了速度。
%timeit x = []; [x.extend(df.values.tolist()) for df in res]; pd.DataFrame(x)
10000 loops, best of 3: 196 µs per loop
%timeit pd.Series(pd.concat(res, axis=1).values.ravel()).dropna()
1000 loops, best of 3: 920 µs per loop
%timeit pd.concat(res, axis=1).stack().reset_index(drop=True)
1000 loops, best of 3: 902 µs per loop
%timeit pd.DataFrame(pd.concat(res, axis=1).values.ravel(), columns=['col']).dropna()
1000 loops, best of 3: 1.07 ms per loop
%timeit pd.Series(np.concatenate([df.values.ravel() for df in res]))
10000 loops, best of 3: 70.2 µs per loop

好像
pd.Series(np.concatenate([df.values.ravel() for df in res]))

是最快的。

09-25 18:27
查看更多