遍历并覆盖 pandas 数据框中的特定值

Iterate through and overwrite specific values in a pandas dataframe

我有一个大型数据框整理了一堆篮球数据(下面的屏幕截图)。 Opp Lineup右边的每一列都是一个虚拟变量,表示该球员(在列名中表示)是否在当前阵容中(列名的最后一部分是球队名称,需要与对手列进行比较确保不同球队中号码和名字相同的两名球员不会搞砸)。我知道遍历 pandas 数据框(iterrows、itertuples、iteritems)的几种方法,但我不知道完成我需要的方法,这是针对每一列中的每一行:

  1. 将球队 (columnname.split()[2:]) 与对手列(LSU 球员除外)进行比较
  2. 查看名称 (columnname.split()[:2]) 是否在 Opp 阵容中,或者对于 LSU 球员,阵容
  3. 如果满足以上条件,则将那个值替换为1,否则保留为0

遍历数据帧并完成此任务的最佳方法是什么?在这种情况下,速度并不重要。我理解所有涉及的逻辑,只是我对 pandas 不够熟悉,不知道如何遍历它,并且尝试了我在 Google 上看到的各种东西都不起作用。

考虑 reshape/pivot 解决方案,因为您的数据是宽格式,但您需要比较长格式的值 row-wise。因此,首先 melt 您的数据,以便所有列 headers 成为实际列 'Player' 及其对应的值 'IsInLineup'。 运行 您对虚拟值的条件比较,然后转向原始结构,玩家跨列 headers。当然,我没有实际数据来全面测试这个例子。

# MELT 
reshapedf = pd.melt(df, id_vars=['Opponent', 'Lineup', 'Minutes', 'Plus Minus', 
                                 'Plus Minus Per Minute', 'Opp Lineup'], 
                    var_name='Player', value_name='IsInLineup')

# APPLY FUNCTION (SPLITTING VALUE AND THEN JOINING FOR SUBSET STRING)
reshapedf['IsInLineup'] = reshapedf.apply(lambda row: (' '.join(row['Player'].split(' ')[:2]) in row['Opp Lineup'] and
                                                       ' '.join(row['Player'].split(' ')[2:]) in row['Opponent'])*1, axis=1)

# PIVOT (UNMELT)
df2 = reshapedf.pivot_table(index=['Opponent', 'Lineup', 'Minutes', 'Plus Minus', 
                                   'Plus Minus Per Minute', 'Opp Lineup'], columns='Player').reset_index()
df2.columns = df2.columns.droplevel(0).rename(None)
df2.columns = df.columns

如果上面的 lambda 函数看起来有点复杂,请尝试等效地应用定义的函数():

# APPLY FUNCTION (SPLITTING VALUE AND THEN JOINING FOR SUBSET STRING)
def f(row):
    if (' '.join(row['Player'].split(' ')[:2]) in row['Opp Lineup'] and \
        ' '.join(row['Player'].split(' ')[2:]) in row['Opponent']):
        return 1
    else:
        return 0

reshapedf['IsInLineup'] = reshapedf.apply(f,axis=1)

我最终使用了变通方法。我通过使用 df.iterrows 进行迭代,并为每个迭代创建一个列表,在其中检查我想要的值,然后将 0 或 1 附加到临时列表。然后我只是将它插入到数据框中。可能不是最有效的记忆方式,但它有效。