在没有元素出现在其原始位置的情况下打乱数据帧值(无序)



Python 3.10/Pandas 1.1.3

给定此代码:

import pandas as pd

data = {'a': ['AA','BB','CC','DD', 'EE', 'FF', 'GG'],
'b': [11, 22, 33, 44, 55, 66, 77],
}

df = pd.DataFrame(data, columns=['a','b'])
df.a
print (df)

其产生:

a   b
0  AA  11
1  BB  22
2  CC  33
3  DD  44
4  EE  55
5  FF  66
6  GG  77

我需要了解如何在不允许生成的数据帧的任何b值与其原始a值相关联的条件下打乱列b的值。

使用以下函数找到重新映射列的方法:

def derange(x):
res = x
while np.any(res == x):
res = np.random.permutation(x)
return res

然后将其应用于任何列:

df['b'] = derange(df['b'])

方法是生成排列,直到一个排列足够好。期望的尝试次数是(n/(n-1))^n,其非常快地收敛到e

请注意,对于n=1,期望值实际上趋向于无穷大,这是有道理的,因为您不能对这样的列表进行降级。

也可以决定性地执行去序,因此为了完整性,这里是:

def derange2(x):
n = len(x)
for i in range(n - 1):
j = random.randrange(i + 1, n)
x[i], x[j] = x[j], x[i]

此函数实际上会就地转换列表。

您还可以有一个修改pandas列的版本:

def derange3(df, col):
n = df.shape[0]
for i in range(n - 1):
j = random.randrange(i + 1, n)
df.iat[i, col], df.iat[j, col] = df.iat[j, col], df.iat[i, col]

让我们使用numpy

def rnd(l):
l1 = l.copy()
while True:
np.random.shuffle(l1)
if any(l == l1):
break
else:
return l1

df.b = rnd(df.b.values)

您可以对索引进行混洗,直到它不再与原始索引匹配,然后使用新的混洗索引对df['b']进行排序,并将此新数组分配回df['b']:

idx = df.index.tolist()
while (idx == df.index).any():
np.random.shuffle(idx)

df['b'] = df['b'][idx].values

相关内容

  • 没有找到相关文章

最新更新