小标题:将熊猫愚弄,不要试图变聪明。
我有一个单列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')
强制类型。 E.g。
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)
答案 0 :(得分:5)
print (pd.concat(res, axis=1))
A B C
0 1.0 9 100.0
1 2.0 8 200.0
2 3.0 7 300.0
3 NaN 6 400.0
4 NaN 5 NaN
5 NaN 4 NaN
print (pd.concat(res, axis=1).stack().reset_index(drop=True))
0 1.0
1 9.0
2 100.0
3 2.0
4 8.0
5 200.0
6 3.0
7 7.0
8 300.0
9 6.0
10 400.0
11 5.0
12 4.0
dtype: float64
使用numpy.ravel
进行扁平化的另一种解决方案:
print (pd.Series(pd.concat(res, axis=1).values.ravel()).dropna())
0 1.0
1 9.0
2 100.0
3 2.0
4 8.0
5 200.0
6 3.0
7 7.0
8 300.0
10 6.0
11 400.0
13 5.0
16 4.0
dtype: float64
print (pd.DataFrame(pd.concat(res, axis=1).values.ravel(), columns=['col']).dropna())
col
0 1.0
1 9.0
2 100.0
3 2.0
4 8.0
5 200.0
6 3.0
7 7.0
8 300.0
10 6.0
11 400.0
13 5.0
16 4.0
list comprehension
的解决方案:
print (pd.Series(np.concatenate([df.values.ravel() for df in res])))
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
dtype: int64
答案 1 :(得分:2)
我会使用list comphrension,例如:
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]))
是最快的。