[英]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
关于数据的一些警告:
我试过的:
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.