为何Pandas填充NaN值顺序错误?如何按时间戳匹配填充
问题描述
尝试用一个DataFrame(源数据)填充另一个DataFrame的NaN值,要求仅按**timestamp(时间戳)**匹配填充,缺失的2021-12保留NaN。
源DataFrame(含缺失时间戳)
price timestamp 2021-10 2.60 2021-11 1.85 2022-01 12.20 2022-02 15.50 2022-03 16.00 2022-04 22.05 2022-05 16.80 2022-06 21.55 2022-07 65.45 2022-08 30.80 2022-09 5.10 2022-10 21.40
注:2021-12时间戳缺失。
待填充的目标DataFrame
price timestamp 2021-10 NaN 2021-11 NaN 2021-12 NaN 2022-01 NaN 2022-02 NaN 2022-03 NaN 2022-04 NaN 2022-05 NaN 2022-06 NaN 2022-07 NaN 2022-08 NaN 2022-09 NaN 2022-10 NaN
错误代码及结果
使用以下代码填充:
creator_primary_sales_dataFrame=creator_primary_sales_dataFrame.reset_index() creator_primary_sales=creator_primary_sales.reset_index() creator_primary_sales_dataFrame=creator_primary_sales.fillna(creator_primary_sales_dataFrame)
得到错误结果(填充错位):
timestamp price 0 2021-10 2.60 1 2021-11 1.85 2 2021-12 12.20 3 2022-01 15.50 4 2022-02 16.00 5 2022-03 22.05 6 2022-04 16.80 7 2022-05 21.55 8 2022-06 65.45 9 2022-07 30.80 10 2022-08 5.10 11 2022-09 21.40 12 2022-10 NaN
期望输出
timestamp price 0 2021-10 2.60 1 2021-11 1.85 2 2021-12 NaN 3 2022-01 12.20 4 2022-02 15.50 5 2022-03 16.00 6 2022-04 22.05 7 2022-05 16.80 8 2022-06 21.55 9 2022-07 65.45 10 2022-08 30.80 11 2022-09 5.10 12 2022-10 21.40
原因分析
你用reset_index()把两个DataFrame的时间戳索引转换成了普通的整数行索引(0,1,2...),但源DataFrame因为缺失2021-12,行数比目标DataFrame少1行。fillna()默认是按行索引位置匹配填充,而非按时间戳内容匹配,导致源DataFrame的第2行(对应2022-01的12.20)被填充到目标DataFrame的第2行(2021-12),后续所有数据全部错位,最后源DataFrame没有第12行,导致目标DataFrame的2022-10无法被填充。
解决方案
方案1:保留时间戳索引,直接使用fillna()
不要重置索引,保持timestamp作为两个DataFrame的索引,fillna()会自动按索引(时间戳)匹配填充:
# 确保两个DataFrame的timestamp都是索引(如果不是先设置) # creator_primary_sales_dataFrame = creator_primary_sales_dataFrame.set_index('timestamp') # creator_primary_sales = creator_primary_sales.set_index('timestamp') # 直接填充 creator_primary_sales_dataFrame = creator_primary_sales.fillna(creator_primary_sales_dataFrame)
方案2:使用combine_first()(更直观)
combine_first()会优先使用调用者的数据,缺失的部分用传入的DataFrame填充,同样按索引匹配:
creator_primary_sales_dataFrame = creator_primary_sales.combine_first(creator_primary_sales_dataFrame)
方案3:用merge实现精确匹配
如果需要更灵活的控制,可以用左连接,保留目标DataFrame的所有时间戳,匹配源数据的价格:
result = creator_primary_sales.reset_index().merge( creator_primary_sales_dataFrame.reset_index(), on='timestamp', how='left', suffixes=('_x', '') ).drop('price_x', axis=1).set_index('timestamp')
以上三种方案都能实现按时间戳精确匹配填充,保留2021-12的NaN值。
内容的提问来源于stack exchange,提问作者Emirhan Serveren
相关产品推荐
相关产品推荐

