python - 如何比较两个 Dataframe 并更新其中一个 Dataframe 中的特定列?
问题描述
更新:我对答案有一些问题,并猜测这与行不匹配有关。(更新了 today_df 以便今天和昨天有不同的行数)。
我需要比较昨天的数据框和今天的新数据框来更新今天的数据框上的一列。例如:昨天_df:
fruit price qty comment
apple 1.5 10 In Stock
banana 0.7 20 In Stock
Pear 3.0 5 In Stock
Watermelon 1.2 30 Out Stock
today_df(更新了 today_df 以便今天和昨天的行数不同)
fruit price qty comment
apple 1.5 10
Strawberry 1.7 20
Pineapple 0.9 5
Watermelon 1.2 30
Peach 2.1 10
期望的输出:today_df
fruit price qty comment
apple 1.5 10 In Stock <-- from yesterday
Strawberry 1.7 20 <-- empty
Pineapple 0.9 5 <-- empty
Watermelon 1.2 30 Out Stock <-- From Yesterday
peach 2.1 10 <-- empty
对于 Today's Dataframe,前一天对 Apple 和 Watermelon 的评论被保留,数据中的新信息(草莓和菠萝)留空。
我尝试使用系列映射:
fruit_map = yesterday_df.set_index('fruit')['Comment']
today_df['Comment']=today_df['fruit'].map(fruit_map).fillna(today_df['Comment'])
today_df
但收到此错误:
InvalidIndexError:重新索引仅对具有唯一值的索引对象有效
fruit_map = yesterday_df.set_index('fruit')['Comment']
today_df['Comment']=today_df['fruit'].map(fruit_map).fillna(today_df['Comment'])
today_df
today_df
fruit price qty comment
apple 1.5 10 In Stock
Strawberry 1.7 20
Pineapple 0.9 5
Watermelon 1.2 30 Out Stock
解决方案
您走在正确的道路上,但是您可以利用索引来分配值,因此不需要映射。当您使用系列为数据框分配值时,它将在索引上对齐。这里的关键是确保您使用“fruit”作为两个数据帧的索引。最简单的方法是:
import pandas as pd
from pandas.compat import StringIO
yesterday = """
fruit,price,qty,comment,col to show it works with different shapes
apple,1.5,10,In Stock,bleh
banana,0.7,20,In Stock,blah
Pear,3.0,5,In Stock,bip
Watermelon,1.2,30,Out Stock,bop
"""
today = """
fruit,price,qty,comment
apple,1.5,10,
Strawberry,1.7,20,
Pineapple,0.9,5,
Watermelon,1.2,30,
Peach,2.1,10,
"""
yesterday_df = pd.read_csv(StringIO(yesterday), sep=",").set_index("fruit")
today_df = pd.read_csv(StringIO(today), sep=",").set_index("fruit")
today_df["comment"] = yesterday_df["comment"]
today_df
Out[1]:
price qty comment
fruit
apple 1.5 10 In Stock
Strawberry 1.7 20 NaN
Pineapple 0.9 5 NaN
Watermelon 1.2 30 Out Stock
Peach 2.1 10 NaN
或者,您可以在读取数据时将索引设置为“fruit”并避免set_index
调用。
您可能还想通过小写来清理索引('fruit' 列),因为字符串索引区分大小写。例如,如果昨天你有“Apple”,而今天是“apple”,这是行不通的。
另外,我假设您对更改有关“价格”或“数量”的任何内容不感兴趣。
推荐阅读
- for-loop - 如何使用 Dart 从 for 循环中返回值
- sql - 以降序和随机顺序计数 (*)
- java - 如何在同一台mac上处理多个版本的JDK
- c++ - Visual Studio 2019 不想为 LIB 版本生成 ASM 文件,我做错了什么?
- netsuite - 根据模板的 NetSuite 自定义字段
- javascript - 对象中的箭头函数和简单函数行为
- javascript - 正则表达式删除数字以外的字符并仅在 Angular 6 中允许单个小数点
- django - django模型多个主键
- java - 如果元素是动态的,则无法定位元素
- reactjs - 使用返回对象内的对象的高阶组件的 mapState 函数遇到编译错误