成对交换(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
不同,因为它用最后一个值填充第一个值