我有按ID索引并按value
排序的熊猫数据帧。我想创建一个n=20000的样本大小,其中总共有40000行,并且有2行是连续的/成对的。我想对这两个连续/成对的行进行额外的计算
例如,如果我说样本大小n=2,我想随机选取并找到以下每个选取的距离差。
附加条件:数值差异不能超过4000。
index value distance
cg13869341 15865 1.635450
cg14008030 18827 4.161332
然后距离以下等
cg20826792 29425 0.657369
cg33045430 29407 1.708055
样本原始数据帧
index value distance
cg13869341 15865 1.635450
cg14008030 18827 4.161332
cg12045430 29407 0.708055
cg20826792 29425 0.657369
cg33045430 69407 1.708055
cg40826792 59425 0.857369
cg47454306 88407 0.708055
cg60826792 96425 2.857369
我试着使用df_sample = df.sample(n=20000)
,然后我在想如何获得df_sample
中每个值的下一行时有点不知所措
原始形状为(480136, 14)
如果总是有(偶数,奇数(对并不重要(这减少了一点随机性(,您可以选择n个奇数行并获得下一个偶数:
N = 20000
# get the indices of N random ODD rows
idx = df.loc[::2].sample(n=N).index
# create a boolean mask to identify the rows
m = df.index.to_series().isin(idx)
# select those OR the next ones
df_sample = df.loc[m|m.shift()]
玩具DataFrame(N=3(的示例输出:
index value distance
2 cg12045430 29407 0.708055
3 cg20826792 29425 0.657369
4 cg33045430 69407 1.708055
5 cg40826792 59425 0.857369
6 cg47454306 88407 0.708055
7 cg60826792 96425 2.857369
增加随机性
上述方法的缺点是存在总是有(奇数、偶数(对的偏差。为了克服这一点,我们可以首先删除DataFrame的随机部分,它足够小,仍然可以留下足够的选择来选择行,但足够大,可以在许多位置将(奇数、偶数(对随机移位到(偶数、奇数(对。应根据初始大小和采样大小测试要删除的行的分数。我在这里用了20-30%:
N = 20000
frac = 0.2
idx = (df
.drop(df.sample(frac=frac).index)
.loc[::2].sample(n=N)
.index
)
m = df.index.to_series().isin(idx)
df_sample = df.loc[m|m.shift()]
# check:
# len(df_sample)
# 40000
这是我的第一次尝试(我只是刚刚注意到你的额外限制,我不确定你是否需要确切的样本数量,在这种情况下,你必须在下面的c=c[mask]
行之后做一些篡改(。
import random
# Temporarily reset index so we can have something that we can add one to.
df = df.reset_index(level=0)
# Choose the first index of each pair.
# Use random.sample if you don't want repeats,
# or random.choice if you don't mind them.
# The code below does allow overlapping pairs such as (1,2) and (2,3).
first_indices = np.array(random.sample(sorted(df.index[:-1]), 4))
# Filter out those indices where the diff with the next row down is large.
mask = [abs(df.loc[i, "value"] - df.loc[i+1, "value"]) > 4000 for i in c]
c = c[mask]
# Interleave this array with the same numbers, plus 1.
c = np.empty((first_indices.size * 2,), dtype=first_indices.dtype)
c[0::2] = first_indices
c[1::2] = first_indices + 1
# Filter
df_sample = df[df.index.isin(c)]
# Restore original index if required.
df = df.set_index("index")
希望能有所帮助。关于我使用掩码过滤c
的比特,如果你需要更快的替代方案,这个答案可能会有所帮助:过滤(减少(NumPy阵列