繁体   English   中英

创建一个具有另一列值的新列,以跨索引共享的多个其他列为条件

[英]Creating a new column with value of another column, conditioned on multiple other columns shared across indices

我在 Pandas 中使用了大约 118k 次游戏观察数据集,每个观察结果应该有两个条目。 当我第一次遇到条目 A 时,我需要根据当前观察中的三个值找到另一个观察,并使用不同列的值创建一个新列。 抱歉,如果这不能在所有设备上正确呈现......我不确定如何在 SO 上格式化 Pandas 表,但我的数据看起来像这样:

   date | user_a_id | user_b_id | a_points | b_points | b_wins | a_result
0  12.1     20834     65168         65165      10568      5         W
1  12.1     20834     84163         65165      88452     21         W
2  12.2     20834     61806         65165      25998     19         L
3  12.1     84163     20834         88452      65165     33         L
4  12.3     96844     10196         22609      167005    52         W

包含的每个玩家都有一堆额外的数据,但我们需要创建一个新列的值在b_wins 每一行都是一场比赛的故事,但a_result是用户 A 的比赛结果。 b_wins是一个有用的数据,它告诉我们玩家在比赛中的经验,我相信这将具有很高的预测价值,所以放弃它是不明智的。

在本示例中,第 1 行和第 3 行讲述了同一个游戏的故事。 我需要df.iloc[3].at['b_wins']才能转到df.iloc[1]名为a_wins的新列,反之亦然。 由此产生的两个索引将如下所示:

   date | user_a_id | user_b_id | a_points | b_points | b_wins | a_result | a_wins
1  12.1     20834     84163         65165      88452     21         W         33
3  12.1     84163     20834         88452      65165     33         L         21

关于数据的一些警告:

  • 不是每个游戏都有一对。 这些数据是从网站上抓取的,非常混乱。 可能只有一个观察结果,这没关系。
  • 没有游戏ID,所以我只能匹配日期和切换的用户ID号。
  • 有很多重赛。 因此,虽然我可以匹配切换后的 ID 号,但我也无法按日期过滤它们
  • 到目前为止,我的大部分工作都是在 Colab Notebook 中完成的。 我第一次开始使用 python shell,没有骰子。

我试过的:

df['a_wins'] = df['user_a_id'].apply(lambda x: df.loc[df["user_b_id"] == x, "b_wins"].values)

似乎偶尔工作。 我没有得到每一个值,也没有得到重新匹配。 为了尝试按日期过滤,我尝试了:

for i in df['date']:
  grouped = df.groupby['date'].get_group(i)
  df['a_wins'] = grouped['user_a_id'].apply(lambda x: grouped.loc[grouped["user_b_id"] == x, "b_wins"].values)

也只能偶尔工作。 两者都需要永远! :)

创建缺失的列:

# initialise a_wins, b_result
df['a_wins'] = None
df['b_result'] = df['a_result'].replace({'W':'L','L':'W'})

想法是交换内容,使较小的id始终a

# which values to swap
df['swap'] = df['user_a_id'] > df['user_b_id']

创建具有相应列名的列表

# works for the data you posted, might want to adjust.
a_list = sorted([a for a in df.columns if 'a_' in a])
b_list = sorted([b for b in df.columns if 'b_' in b])

在满足切换条件的地方交换a / b内容:

for a, b in zip(a_list, b_list):
    df.loc[df['swap'], a], df.loc[df['swap'], b] = df[df['swap']][b], df[df['swap']][a]

输出:

date    user_a_id   user_b_id   a_points    b_points    b_wins  a_result    swap    a_wins  b_result
0   12.1    20834   65168   65165   10568   5   W   False   None    L
1   12.1    20834   84163   65165   88452   21  W   False   None    L
2   12.2    20834   61806   65165   25998   19  L   False   None    W
3   12.1    20834   84163   65165   88452   None    W   True    33  L
4   12.3    10196   96844   167005  22609   None    L   True    52  W

编辑:

现在可以通过按date, user_a_id, user_b_id分组并填充None值来复制条目:

df = df.groupby(['date','user_b_id', 'user_a_id'])[df.columns].fillna(method='ffill').fillna(method='bfill')

现在,您可以使用交换列恢复原始格式:

for a, b in zip(a_list, b_list):
    df.loc[df['swap'], a], df.loc[df['swap'], b] = df[df['swap']][b], df[df['swap']][a]

输出:

date    user_a_id   user_b_id   a_points    b_points    b_wins  a_result    a_wins  b_result    swap
0   12.1    20834   65168   65165   10568   5.0 W   33.0    L   False
1   12.1    20834   84163   65165   88452   21.0    W   33.0    L   False
2   12.2    20834   61806   65165   25998   19.0    L   33.0    W   False
3   12.1    84163   20834   88452   65165   33.0    L   21.0    W   True
4   12.3    96844   10196   22609   167005  52.0    W   NaN L   True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM