【问题标题】:Correct way to iterate over two dataframes to set specific values based on the value of another df迭代两个数据帧以根据另一个 df 的值设置特定值的正确方法
【发布时间】:2023-01-24 16:55:06
【问题描述】:

编辑以添加更容易重现的数据框

我有两个看起来像这样的数据框:

df1

index = [0,1,2,3,4,5,6,7,8]
a = pd.Series([John Smith, John Smith, John Smith, Kobe Bryant, Kobe Bryant, Kobe Bryant, Jeff Daniels, Jeff Daniels, Jeff Daniels],index= index)
b = pd.Series([7/29/2022, 8/7/2022, 8/29/2022, 7/9/2022, 7/29/2022, 8/9/2022, 7/28/2022, 8/8/2022, 8/28/2022],index= index)
c = pd.Series([185, 187, 186.5, 212.5, 217.5, 220.5, 211.1, 210.5, 213],index= index)
d = pd.Series([],index= index)
df1 = pd.DataFrame(np.d_[a,b,c],columns = ["Name","Date","Weight","Goal"])

或这种格式的 df1:

Name Date Weight Goal
John Smith 7/29/2022 185 NaN
John Smith 8/7/2022 187 NaN
John Smith 8/29/2022 186.5 NaN
Kobe Bryant 7/9/2022 212.5 NaN
Kobe Bryant 7/29/2022 217.5 NaN
Kobe Bryant 8/9/2022 220.5 NaN
Jeff Daniels 7/28/2022 211.1 NaN
Jeff Daniels 8/8/2022 210.5 NaN
Jeff Daniels 8/28/2022 213 NaN

df2

index = [0,1,2]
a = pd.Series([John Smith, Kobe Bryant, Jeff Daniels],index= index)
b = pd.Series([195,230,220],index= index)
c = pd.Series([],index= index)
df2 = pd.DataFrame(np.c_[a,b],columns = ["Name", "Weight Goal"]) 

或这种格式的 df2:

Name Weight Goal
John Smith 195
Kobe Bryant 230
Jeff Daniels 220

我想要做的是遍历 df1 并从 df2 为每个玩家设置各自的体重目标......但我只想在八月这样做,我想忽略七月的日期。

我知道我不应该将 for 循环与 dataframe/pandas 一起使用,但我认为我用一个人展示我的思维过程可能表明我试图通过我的代码尝试实现的意图。

for player in df1['Name']:
    df1 = df1.loc[(df1['Name'] == f'{player}') & (df1['Date'] > '8/1/2022')]
    df1.at[df2['Name'] == f'{player}',  'Goal'] = (df2.loc[df2.Name == f'{player}']['Weight Goal'])

这只是最终提供了一个空数据框和一个带有复制警告的设置。我知道这不是正确的方法,但我认为这可能有助于指导我。

谢谢你。

【问题讨论】:

  • 你好,请举一个更容易重现的例子(例如:df = pd.dataframe({..

标签: python pandas dataframe


【解决方案1】:

如果我正确地理解了您之后的输出(堆栈溢出提示:提供所需输出的样本以帮助人们尝试回答您的问题可能很有用),那么这应该有效:

# make the Date column into datetime type so it is easier to filter on
df1 = df1.assign(Date=pd.to_datetime(df1.Date))

# separate out the august rows from the other months
df1_august = df1.loc[df1.Date.apply(lambda x: x.month == 8)]
df1_other_months = df1.loc[df1.Date.apply(lambda x: x.month != 8)]

# use a merge rather than a loop to get WeightGoal column in place
df1_august_merged = df1_august.merge(df2, on="Name")

# finally add the rows for the other months back in
final_df = pd.concat([df1_august_merged, df1_other_months])

print(final_df)
           Name       Date  Weight  Goal  Weight Goal
0    John Smith 2022-08-07   187.0   NaN        195.0
1    John Smith 2022-08-29   186.5   NaN        195.0
2   Kobe Bryant 2022-08-09   220.5   NaN        230.0
3  Jeff Daniels 2022-08-08   210.5   NaN        220.0
4  Jeff Daniels 2022-08-28   213.0   NaN        220.0
0    John Smith 2022-07-29   185.0   NaN          NaN
3   Kobe Bryant 2022-07-09   212.5   NaN          NaN
4   Kobe Bryant 2022-07-29   217.5   NaN          NaN
6  Jeff Daniels 2022-07-28   211.1   NaN          NaN

【讨论】:

  • 本!谢谢你的提示,我很感激,对提问很陌生,我想继续学习提问,让所有像你这样提供巨大帮助的人都能更轻松地提问。这个输出看起来和我昨晚正在寻找和睡觉的一模一样,我有一种感觉 df.apply & lambda 将是我想要的!!谢谢 我一拿到电脑就试试。
  • @AKtheAT 没问题,希望对您有所帮助!
猜你喜欢
  • 2019-11-02
  • 2020-07-29
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多