成对交换(Python、Pandas、NumPy)
给定如下数据帧:成对交换(Python、Pandas、NumPy),python,pandas,numpy,Python,Pandas,Numpy,给定如下数据帧: ID, side, col 10, home, a_h 10, away, a_a 11, home, b_h 11, away, b_a ... ID, side, col 10, home, a_a 10, away, a_h 11, home, b_a 11, away, b_h ... 我想交换值a_h和a_a,b_h和b_a,并制作如下数据帧: ID, side, col 10, home, a_h 10, away, a_a 11, home, b_h 1
ID, side, col
10, home, a_h
10, away, a_a
11, home, b_h
11, away, b_a
...
ID, side, col
10, home, a_a
10, away, a_h
11, home, b_a
11, away, b_h
...
我想交换值a_h
和a_a
,b_h
和b_a
,并制作如下数据帧:
ID, side, col
10, home, a_h
10, away, a_a
11, home, b_h
11, away, b_a
...
ID, side, col
10, home, a_a
10, away, a_h
11, home, b_a
11, away, b_h
...
我可以通过使用for循环来实现这一点,但我想知道是否有更有效的方法使用numpy或pandas来实现这一点
谢谢 IIUC
groupby
颠倒顺序,然后重新分配
df['col']=df.groupby('ID',sort=False).col.apply(lambda x : x.iloc[::-1]).values
df
Out[104]:
ID side col
0 10 home a_a
1 10 away a_h
2 11 home b_a
3 11 away b_h
尝试以下操作:
df['col']=df['col'].替换({'a_h':'a_a','a_a':'a_h'})
和df['col']=df['col'].替换({'b_h':'b_a','b_a':'b_h'})
。有关replace()的详细信息,请单击此处:使用
IFF这是一个真正的两两交换,数据帧被排序,以便ID正好有两个观察值出现在连续的行中,我们可以使用两个移位并从每个行中切片适当的行
df['shift_col'] = pd.concat([df['col'].shift()[1::2], df['col'].shift(-1)[::2]])
# ID side col shift_col
#0 10 home a_h a_a
#1 10 away a_a a_h
#2 11 home b_h b_a
#3 11 away b_a b_h
这里的好处是,对于许多
id
,这将比GroupBy.apply伸缩性好得多。缺点是它容易出错 如果你有100000行呢?您需要手动创建词典吗?@rafaelc如果有100000行,此解决方案适用。字典按照要交换的对的数量进行缩放,而不是数据帧中的行数。我知道它是有效的。但是,您要在字典中手动写入1000000个条目吗?字典按照要交换的对的数量进行缩放,而不是数据帧中的行数。只有两对可以交换。我不确定你是否明白我说的话。哈哈哈。您已经手动编写了{'a_h':'a_a','a_a':'a_h'}
,然后{'b_h':'b_a','b_a':'b_h'}
。假设你也有c_h
,d_h
,e_h
,f_h
,g_h
一直到z_h
。然后,当它到达z_h
时,它会从a_i
开始,然后b_i
,然后c_i
等等。您是否要手动编写每个字典,每个字典都有两对进行交换,并对所有字典调用手动替换?因为这显然是一个不可伸缩的解决方案,所以您可以为数据帧的大小和要交换的对的数量提供更多的上下文吗?即使为您提到的预期for循环添加伪代码,也会给我们一些启示。很抱歉,还不够清楚。根据我的数据,@rafaelc的代码就是我想要做的。谢谢大家!@rafaelc我不认为你的回答像最初的问题那样解决了两两交换问题。。。如果我理解np.roll,这仅用于移位值(这仅在a_a和a_h,&b_a和b_h有序且方便地彼此相邻时才有用)。其思想是,当您groupby.apply
时,该函数应用于每个组中的col
系列。每组有2个项目-主场和客场-当你滚动它们时,你只需交换它们的位置np.roll
的工作方式与pd.Series.shift
不同,因为它用最后一个值填充第一个值