Pandas - 随机替换10%的行与其他行

时间:2018-04-23 23:38:45

标签: python pandas

我想随机选择df中所有行的10%,并用df中随机抽样的现有行替换每一行。

要随机选择10%的行rows_to_change = df.sample(frac=0.1),我可以使用replacement_sample = df.sample(n=1)获得一个新的随机现有行但是如何将它们放在一起以快速迭代整个10%?

df包含数百万行x~100列。

示例df:

df = pd.DataFrame({'A':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],'B':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],'C':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]})

    A   B   C
0   1   1   1
1   2   2   2
2   3   3   3
3   4   4   4
4   5   5   5
5   6   6   6
6   7   7   7
7   8   8   8
8   9   9   9
9   10  10  10
10  11  11  11
11  12  12  12
12  13  13  13
13  14  14  14
14  15  15  15

让我们说它随机抽样索引2,13以替换随机选择的索引6,9最终的df看起来像:

    A   B   C
0   1   1   1
1   2   2   2
2   7   7   7
3   4   4   4
4   5   5   5
5   6   6   6
6   7   7   7
7   8   8   8
8   9   9   9
9   10  10  10
10  11  11  11
11  12  12  12
12  13  13  13
13  10  10  10
14  15  15  15

2 个答案:

答案 0 :(得分:2)

您可以随机抽取样本,然后取另一个相同大小的随机样本,并用原始样本替换这些索引处的值。

import pandas as pd

df = pd.DataFrame({'A': range(1,15), 'B': range(1,15), 'C': range(1,15)})

samp = df.sample(frac=0.1)
samp
# returns:
    A   B   C
6   7   7   7
9  10  10  10

replace = df.loc[~df.index.isin(samp.index)].sample(samp.shape[0])
replace
# returns:
   A  B  C
3  4  4  4
7  8  8  8

df.loc[replace.index] = samp.values

这会复制没有替换的行

df
# returns:
     A   B   C
0    1   1   1
1    2   2   2
2    3   3   3
3    7   7   7
4    5   5   5
5    6   6   6
6    7   7   7
7   10  10  10
8    9   9   9
9   10  10  10
10  11  11  11
11  12  12  12
12  13  13  13
13  14  14  14
14  15  15  15

要替换样本,请在定义replace = True

时使用关键字samp

答案 1 :(得分:0)

@詹姆斯'答案是一个聪明的熊猫解决方案。但是,鉴于您注意到您的数据集长度在数百万之间,您还可以考虑NumPy,因为Pandas通常会带来显着的性能开销。

def repl_rows(df: pd.DataFrame, pct: float):
    # Modifies `df` inplace.
    n, _ = df.shape
    rows = int(2 * np.ceil(n * pct))  # Total rows in both sets
    idx = np.arange(n, dtype=np.int)  # dtype agnostic
    full = np.random.choice(idx, size=rows, replace=False)
    to_repl, repl_with = np.split(full, 2)
    df.values[to_repl] = df.values[repl_with]

步骤:

  • 以整数形式获取目标行。
  • 获取与索引长度相同的NumPy范围数组。如果您有不同的日期时间索引,可能会提供比使用索引本身更多的稳定性。 (我不完全确定,有什么可以玩的。)
  • 此索引中的样本没有替换,样本大小是您想要操作的行数的2倍。
  • 将结果分成两半以获得目标和替换。应该比拨打choice()两次更快。
  • 使用to_repl的值替换repl_with位置。