pandas 数据框的连接列表,但忽略列名
Concat list of pandas data frame, but ignoring column name
Sub-title: 把它装傻pandas,别耍小聪明了。
我有一个 single-column pandas 数据框的列表 (res
),每个数据框都包含相同类型的数字数据,但每个都有不同的列名。行索引没有意义。我想将它们放入一个非常长的 single-column 数据框中。
当我执行 pd.concat(res)
时,每个输入文件得到一列(以及 NaN 单元格的加载和加载)。我已经为参数 (*) 尝试了各种值,但 none 满足了我的要求。
编辑:示例数据:
res = [
pd.DataFrame({'A':[1,2,3]}),
pd.DataFrame({'B':[9,8,7,6,5,4]}),
pd.DataFrame({'C':[100,200,300,400]}),
]
我有一个ugly-hack解决方案:复制每个数据框并给它一个新的列名:
newList = []
for r in res:
r.columns = ["same"]
newList.append(r)
pd.concat( newList, ignore_index=True )
当然这不是最好的方法??
顺便说一句, 类似,但我的问题更简单,因为我不想维护索引。 (我也从 N single-column 个数据帧的列表开始,而不是单个 N-column 个数据帧。)
*:例如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)
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
我会使用列表理解,例如:
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]))
最快。
Sub-title: 把它装傻pandas,别耍小聪明了。
我有一个 single-column pandas 数据框的列表 (res
),每个数据框都包含相同类型的数字数据,但每个都有不同的列名。行索引没有意义。我想将它们放入一个非常长的 single-column 数据框中。
当我执行 pd.concat(res)
时,每个输入文件得到一列(以及 NaN 单元格的加载和加载)。我已经为参数 (*) 尝试了各种值,但 none 满足了我的要求。
编辑:示例数据:
res = [
pd.DataFrame({'A':[1,2,3]}),
pd.DataFrame({'B':[9,8,7,6,5,4]}),
pd.DataFrame({'C':[100,200,300,400]}),
]
我有一个ugly-hack解决方案:复制每个数据框并给它一个新的列名:
newList = []
for r in res:
r.columns = ["same"]
newList.append(r)
pd.concat( newList, ignore_index=True )
当然这不是最好的方法??
顺便说一句,
*:例如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)
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
我会使用列表理解,例如:
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]))
最快。