【发布时间】:2021-06-17 19:18:07
【问题描述】:
我现在很难合并和更新 Pandas 数据框。
我有一堆用 pandas 解析的 CSV 文件(这不是 问题)。在极少数情况下,我有多个文件包含一些列 存在于两个文件中。
例如,假设我有:
import pandas as pd
a = pd.DataFrame({"A": [0, 1, 2, 3], "B": [4, 5, 6, 7]}, index=[0,1,2,3])
b = pd.DataFrame({"A": [11, 12, 13, 14]}, index=[41,51,61,71])
c = pd.DataFrame({"A": [110, 111, 113]}, index=[0,1,3])
我想要的是这个数据框:
A B
0 110 4
1 111 5
2 2 6
3 113 7
41 11 NaN
51 12 NaN
61 13 NaN
71 14 NaN
Pandas 有这个不错的指南:Merge, join, concatenate and compare。但是我 无法找到我想要实现的解决方案。
例如a.join(b, how="outer") 引发ValueError: columns overlap but no suffix specified: Index(['A'], dtype='object')。路过rsuffix="R"
不是一个选项,因为最终结果是:
A B AR
0 0.0 4.0 NaN
1 1.0 5.0 NaN
2 2.0 6.0 NaN
3 3.0 7.0 NaN
41 NaN NaN 11.0
51 NaN NaN 12.0
61 NaN NaN 13.0
71 NaN NaN 14.0
不是我想要的。
pd.merge(a, b, how="outer") 看起来很有希望,但也不完全正确,
因为索引被忽略了:
A B
0 0 4.0
1 1 5.0
2 2 6.0
3 3 7.0
4 11 NaN
5 12 NaN
6 13 NaN
7 14 NaN
传递 left_index=True 和 right_index=True 会产生一个类似于
.join(..., rsuffix="_x", lsuffix="_y"),所以不是我想要的。
使用update 几乎是我想要的,a.merge(c) 会将a 修改为
A B
0 110.0 4
1 111.0 5
2 2.0 6
3 113.0 7
但是a.update(b) 什么都不做(我假设是因为a 和b 的索引是
分离)。
那么,我想用一行代码实现吗?
编辑
我想出了这个:
> lll = pd.concat([a,b, c]).sort_index()
> pd.concat([a,b,c]).sort_index().drop_duplicates().groupby(a.index).last()
A B
0 110 4.0
1 111 5.0
2 2 6.0
3 113 7.0
41 11 NaN
51 12 NaN
61 13 NaN
71 14 NaN
这就是我想要的,问题是:这是正确的还是只是巧合 这会产生与我想要的结果相同的结果吗?
您如何确定哪个“A”列具有优先权?
按照我阅读文件的顺序。这些文件由设备生成(其中 对我来说是一种“黑匣子”)并生成带有日期的文件。所以我 做:
tasks = [parse_csv_file(fn) for fn in sorted(glob.glob("*.csv"))]
results = await asyncio.gather(*tasks)
我想做(没有错误检查,因为这是一个例子):
results = iter(results)
merged_df = next(results)
for df in results:
merged_df = the_magic_function_Im_looking_for(df)
【问题讨论】:
-
您如何确定哪个“A”列具有优先权?
-
按照我读取数据文件的顺序(文件名中有日期),所以我这样做:
for fn in sorted(glob.glob("*.csv")): ...