根据 Pandas 中的列内容连接两个 csv 文件
Posted
技术标签:
【中文标题】根据 Pandas 中的列内容连接两个 csv 文件【英文标题】:Concatenate two csv files based on column content in Pandas 【发布时间】:2022-01-17 06:06:57 【问题描述】:我有两个带有示例数据的大型 CSV 文件,如下所示:
df1 =
Index Fruit Vegetable
0 Mango Spinach
1 Berry Carrot
2 Banana Cabbage
df2 =
Index Unit Price
0 Mango 30
1 Artichoke 45
2 Banana 12
3 Berry 10
4 Cabbage 25
5 Rice 40
6 Spinach 34
7 Carrot 08
8 Lentil 12
9 Pot 32
我想创建以下数据框:
df3 =
Index Fruit Price Vegetable Price
0 Mango 30 Spinach 34
1 Berry 10 Carrot 08
2 Banana 12 Cabbage 25
我希望在 df1 中逐行比较每个单位的价格。如果价格在 5 美元以内,我想将它们输出到单独的数据框中,如下所示:
df4 =
Index Fruit Price Vegetable Price
0 Mango 30 Spinach 34
1 Berry 10 Carrot 08
实现这一目标的通用方法是什么?提前谢谢你。
【问题讨论】:
我建议在这里使用两个joins 将来自 df2 的价格信息与 df1 结合起来。 【参考方案1】:您可以使用replace
基于df2
创建价格数据框,然后使用join
与原始数据连接。
请注意,不鼓励重复的列名:
# print to see what it does
item_prices = dict(zip(df2.Unit, df2.Price))
out = df1.join(df1.replace(item_prices).add_suffix('_Price')).sort_index(axis=1)
输出:
Fruit Fruit_Price Vegetable Vegetable_Price
Index
0 Mango 30 Spinach 34
1 Berry 10 Carrot 8
2 Banana 12 Cabbage 25
对于下一个问题,您需要一个布尔 loc 访问权限:
out[abs(out['Fruit_Price'] - out['Vegetable_Price']) < 5]
或query
:
out.query('abs(Fruit_Price-Vegetable_Price)<5')
输出:
Fruit Fruit_Price Vegetable Vegetable_Price
Index
0 Mango 30 Spinach 34
1 Berry 10 Carrot 8
【讨论】:
如果 df2 中的单位名称是 Mango_123、Spinach_435 等,对代码的修改是什么。我相信在加入之前应该与 df1 进行字符串匹配,但不知道该怎么做。 【参考方案2】:您可以使用双重合并:
fruit = df1[['Fruit']].merge(df2.rename(columns='Unit': 'Fruit'), on='Fruit')
veggie = df1[['Vegetable']].merge(df2.rename(columns='Unit': 'Vegetable'), on='Vegetable')
df3 = pd.concat([fruit, veggie], axis=1)
print(df3)
# Output:
Fruit Price Vegetable Price
0 Mango 30 Spinach 34
1 Berry 10 Carrot 8
2 Banana 12 Cabbage 25
然后
df4 = df3[np.abs(np.subtract(*out['Price'].values.T)) <= 5]
print(df4)
# Output:
Fruit Price Vegetable Price
0 Mango 30 Spinach 34
1 Berry 10 Carrot 8
【讨论】:
谢谢,这也有效。但是,我在上面的答案中也发布了一个问题-如果 df2 中的单位名称是 Mango_123、Spinach_435 等,对代码的修改是什么。我相信在加入之前应该与 df1 进行字符串匹配但不确定怎么做。【参考方案3】:一种通用的替代方法(可以处理任意数量的类别)是在之前(使用melt
)和之后(使用pivot
)重塑。这样做的好处是可以创建一个非常方便明确识别价格类别的 MultiIndex:
out = (df1.melt(id_vars='Index', value_name='Unit')
.merge(df2.drop(columns='Index'), on='Unit')
.pivot(index='Index', columns='variable', values=['Unit', 'Price'])
)
输出:
Unit Price
variable Fruit Vegetable Fruit Vegetable
Index
0 Mango Spinach 30 34
1 Berry Carrot 10 8
2 Banana Cabbage 12 25
对 diff ≤ 5 的行进行子集化:
out[out['Price'].diff(axis=1).abs().le(5).any(1)]
输出:
Unit Price
variable Fruit Vegetable Fruit Vegetable
Index
0 Mango Spinach 30 34
1 Berry Carrot 10 8
【讨论】:
以上是关于根据 Pandas 中的列内容连接两个 csv 文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 Pandas [with key column] 将 CSV 与不同的列组合
Pandas:连接多个 .csv 文件并返回聚合了同名列的 Dataframe
使用 pandas 连接两个数据框中的不同列(并附加相似的列)
从两个熊猫系列(csv的列作为DataFrame)创建元素字典