如何用Pandas将PropTax行金额按60-40拆分并替换原行?
问题描述
给定如下DataFrame:
df = pd.DataFrame.from_dict({ 'date': ['2022-07-12 00:00:00', '2022-10-25 00:00:00', '2022-04-07 00:00:00'], 'desc': ['Southwest', 'CntyTax', 'Chef le rey'], 'amount': [1024.32,17521.50, 93.49], 'category': ['Vacation', 'PropTax', 'Dinner'] })
需求:将category为"PropTax"的行的amount按60-40比例拆分,用两行数据替换原行。两行保留原行的date和desc,一行amount为原金额的60%、category设为"PropTax1";另一行amount为原金额的40%、category设为"PropTax2"。
尝试思路:
- 将原PropTax行复制到
dfPropTax1和dfPropTax2两个DataFrame - 分别更新两个DataFrame的
amount字段和category - 从原DataFrame删除原PropTax行
- 将两个DataFrame追加到原DataFrame
遇到的问题:更新金额值时出现NaN,无法正确赋值。
用户尝试代码:
# 最新尝试代码(更新金额时出现NaN) dft = pd.DataFrame.from_dict({ 'date': ['2022-07-12 00:00:00', '2022-10-25 00:00:00', '2022-04-07 00:00:00'], 'desc': ['Southwest', 'CntyTax', 'Chef le rey'], 'amount': [1024.32,17521.50, 93.49], 'category': ['Vacation', 'PropTax', 'Dinner'] }) print(dft) print('(Rows, Cols)', dft.shape) PropTaxTotal = dft.amount[dft.category.isin(['PropTax'])] PropTax1 = PropTaxTotal * 0.55 PropTax2 = PropTaxTotal * 0.45 print("PropTax1: ", PropTax1, "PropTax2: ", PropTax2) print("-----Create row copy in new DF") # Create row copy in new DF dfPropTax1 = dft.loc[dft['category']=='PropTax'].head(1) dfPropTax2 = dft.loc[dft['category']=='PropTax'].head(1) print(dfPropTax1) print('(Rows, Cols)', dfPropTax1.shape) print(dfPropTax2) print("-----Update values appropriatly") # Update values appropriatly dfPropTax1.loc[1, ['amount']] print("Update") dfPropTax1.loc[1, ['amount']] = PropTax1 dfPropTax2.loc[1, ['amount']] = PropTax2 print(dfPropTax1) print('(Rows, Cols)', dfPropTax1.shape) print(dfPropTax2) # drop original PropTax dft = dft.drop(dft[dft.category.isin(['PropTax'])].index) print(dft) print('(Rows, Cols)', dft.shape) # Append new rows dft = dft.append(dfPropTax1,ignore_index=True) dft = dft.append(dfPropTax2,ignore_index=True) print(dft) print('(Rows, Cols)', dft.shape)
解决方案
问题原因
- 筛选子DataFrame时未使用
.copy(),导致dfPropTax1和dfPropTax2是原DataFrame的视图而非独立副本,修改时易触发异常。 - 硬编码索引
1缺乏通用性,若原DataFrame中PropTax行的索引变动,代码会直接失效。 - 代码中误用55-45比例,与需求的60-40不符。
修正后的代码
import pandas as pd dft = pd.DataFrame.from_dict({ 'date': ['2022-07-12 00:00:00', '2022-10-25 00:00:00', '2022-04-07 00:00:00'], 'desc': ['Southwest', 'CntyTax', 'Chef le rey'], 'amount': [1024.32,17521.50, 93.49], 'category': ['Vacation', 'PropTax', 'Dinner'] }) # 1. 筛选PropTax行并创建独立副本 proptax_row = dft[dft['category'] == 'PropTax'].copy() # 2. 生成拆分后的两行数据 df_prop1 = proptax_row.copy() df_prop1['amount'] = df_prop1['amount'] * 0.6 df_prop1['category'] = 'PropTax1' df_prop2 = proptax_row.copy() df_prop2['amount'] = df_prop2['amount'] * 0.4 df_prop2['category'] = 'PropTax2' # 3. 删除原PropTax行 dft = dft[dft['category'] != 'PropTax'] # 4. 合并拆分后的行(替代已弃用的append方法) dft = pd.concat([dft, df_prop1, df_prop2], ignore_index=True) print(dft)
代码说明
- 用
.copy()明确创建独立副本,彻底避免视图修改的异常问题。 - 直接修改列值,不依赖固定索引定位,适配不同场景的DataFrame结构。
- 使用
pd.concat()替代已被弃用的append()方法(pandas 2.0+版本已移除append())。 - 严格按照需求的60-40比例拆分金额。
内容的提问来源于stack exchange,提问作者Craig Bender
相关产品推荐
相关产品推荐

