Python 使用pd.update仅更新数据帧的一个片段
我有一个大熊猫数据框,我试图使用更新函数从第二个数据框中获取一些数据。但是,我只希望第一个数据帧的值在为空时更新。如果已经有一个值,我想保留原始值 我认为这将是非常简单的:使用.loc和isnull来限制更新操作的位置,然后使用map从第二个df获取数据。然而,这种方法做不了什么坏事 下面的MRE使用for循环来实现我想要的。具体来说,它应该在“年”内将所有的南部地区都转移到2021年。正上方是我尝试的代码,它没有任何作用Python 使用pd.update仅更新数据帧的一个片段,python,pandas,Python,Pandas,我有一个大熊猫数据框,我试图使用更新函数从第二个数据框中获取一些数据。但是,我只希望第一个数据帧的值在为空时更新。如果已经有一个值,我想保留原始值 我认为这将是非常简单的:使用.loc和isnull来限制更新操作的位置,然后使用map从第二个df获取数据。然而,这种方法做不了什么坏事 下面的MRE使用for循环来实现我想要的。具体来说,它应该在“年”内将所有的南部地区都转移到2021年。正上方是我尝试的代码,它没有任何作用 import pandas as pd import numpy as
import pandas as pd
import numpy as np
sp = ['Ross', 'Rachel', 'Joey', 'Monica', 'Chandler', 'Phoebe']
sp = sorted(sp * 36)
yrs = list(range(2017, 2020))
years = sorted(yrs * 12)
years = years * 6
months = list(range(1, 13))
months = months * 18
df_data = {'SalesPerson': sp,
'Year': years,
'Month': months,
'Sales':np.random.randint(20, 50, 216)}
df = pd.DataFrame(data=df_data)
df.loc[(df['SalesPerson'] == 'Ross') &
(df['Year'] == 2017), 'Year'] = np.nan
temp_df = df.loc[df['SalesPerson'] =='Ross', 'Year'].copy()
temp_df['Year'] = 2021
merge_dict = dict(zip(temp_df.index, temp_df['Year']))
#WHY DOESN'T UPDATE WORK FOR MY PURPOSE?
#df.loc[df['Year'].isnull(), 'Year'].update(df.index.map(merge_dict))
#df.update(df[df['Year'].isnull()].index.map(merge_dict))
for k in merge_dict.keys():
if pd.isnull(df.loc[k, 'Year']):
df.loc[k, 'Year'] = merge_dict[k]
print(df.to_string())
使用。结果是两个序列的并集,如果调用方序列中的值为Null,则取传递序列中的值
df['Year'] = df['Year'].combine_first(temp_df['Year'])
使用。结果是两个序列的并集,如果调用方序列中的值为Null,则取传递序列中的值
df['Year'] = df['Year'].combine_first(temp_df['Year'])
如果您在temp_df时创建一个pd.DataFrame,而不是一个pd.Series,那么它可以工作
import pandas as pd
import numpy as np
sp = ['Ross', 'Rachel', 'Joey', 'Monica', 'Chandler', 'Phoebe']
sp = sorted(sp * 36)
yrs = list(range(2017, 2020))
years = sorted(yrs * 12)
years = years * 6
months = list(range(1, 13))
months = months * 18
df_data = {'SalesPerson': sp,
'Year': years,
'Month': months,
'Sales':np.random.randint(20, 50, 216)}
df = pd.DataFrame(data=df_data)
# creates incomplete dataframe
df.loc[(df['SalesPerson'] == 'Ross') &
(df['Year'] == 2017), 'Year'] = np.nan
df.to_csv("test.csv")
# creates complete dataframe for Ross, with index matching main df
other = df.loc[(df['SalesPerson'] =='Ross') &
(df['Year'].isnull())]
other['Year'] = 2021
df.update(other)
df.to_csv("test.csv")
如果您在temp_df时创建一个pd.DataFrame,而不是一个pd.Series,那么它可以工作
import pandas as pd
import numpy as np
sp = ['Ross', 'Rachel', 'Joey', 'Monica', 'Chandler', 'Phoebe']
sp = sorted(sp * 36)
yrs = list(range(2017, 2020))
years = sorted(yrs * 12)
years = years * 6
months = list(range(1, 13))
months = months * 18
df_data = {'SalesPerson': sp,
'Year': years,
'Month': months,
'Sales':np.random.randint(20, 50, 216)}
df = pd.DataFrame(data=df_data)
# creates incomplete dataframe
df.loc[(df['SalesPerson'] == 'Ross') &
(df['Year'] == 2017), 'Year'] = np.nan
df.to_csv("test.csv")
# creates complete dataframe for Ross, with index matching main df
other = df.loc[(df['SalesPerson'] =='Ross') &
(df['Year'].isnull())]
other['Year'] = 2021
df.update(other)
df.to_csv("test.csv")
你能详细说明你的问题吗?对于名为Ross的销售人员,输出结果会是什么?所有NaN都应该替换为temp_DF的相同索引值。您能详细说明您的问题吗?名为Ross的销售人员的输出是什么?所有NaN都应该替换为temp_DF的相同索引值。this和@peter curran的解决方案都非常有效。我选择这个是因为它稍微简单一点。这个和@peter curran的解决方案都非常有效。我选择这个是因为它稍微简单一点。这个很好用。选择@shradha的答案是因为它更简单,但我认为在某些用例中,这个答案会很有用。这很好。选择@shradha的答案是因为它更简单,但我认为在某些用例中,这个答案会很有用。