我有一个特殊的问题。我有一个非常大的数据框,我正在尝试。
我的数据看起来像这样(两列x和y):
x,y
1,'a'
1,'b'
1,'c'
3,'a'
3,'b'
3,'c'
6,'a'
6,'b'
6,'c'
我想根据'x'的值进行采样。我想要每32个x值中的一个样本(基于x的变化,所以我想在1到32之间采样一次,即使x中只有一个值在1到32之间)。
我想做点什么:df[df['x'] % 32 == 0]
。问题是x的值不一定是均匀间隔的(虽然它们是“近似”,但并非总是如此 - 例如在给出的例子中)。例如,如果特定子问题中x的所有值都是奇数,则上述采样将返回空数据帧。实际上,我想每32'x采样一次,或者将最接近的值取为第32个值(如果不存在这样的值,则可以接近最接近 - 例如,取下一个可用值是正常的)。
因此,如果我有一系列X [0, 10, 32, 39, 64, 70, 73, 74, 97, 100, 110, 129]
,我想对x值与[0, 32, 64, 97, 129]
匹配的行进行抽样。
理想情况下,我也可以对此操作进行矢量化,因为数据帧通常非常大。
答案 0 :(得分:1)
df = pd.DataFrame({'x': [1, 1, 1, 3, 3, 3, 6, 6, 6],
'y': ['a', 'b', 'c'] * 3})
x = [0, 10, 32, 39, 64, 70, 73, 74, 97, 100, 110, 129]
spacer = 32
X = pd.Series(x)
# For each value `n` in the range 0, 32, 64, ..., 129, find the index location of the
# nearest value in X via `X.sub(n).abs().idxmin()`. Then use these index locations
# to find the actual target values in X via `loc`.
target_vals = X.loc[[X.sub(n).abs().idxmin()
for n in xrange(0, x[-1], spacer)]].tolist() # `range` in Python 3.
>>> target_vals
[0, 32, 64, 97, 129]
# Sample the target values, taking a sample size of 1.
df[df['x'].isin(target_vals)].groupby('x').apply(lambda group: group.sample(1))
答案 1 :(得分:1)
您可以使用列表推导动态创建广告投放箱,然后使用pd.cut
创建群组,并使用groupby
与sample(1)
一起为每32个值' X&#获取一条记录39;
df = pd.DataFrame({'X':np.random.randint(0, 100, 5000),'Y':np.random.choice(list('ABCDEF'),5000)})
bins = [i for i in np.arange(df.X.min(), df.X.max(), 32)] + [np.inf]
df.groupby(pd.cut(df.X,bins=bins), as_index=False).apply(lambda x: x.sample(1).values)
输出:
[[15 'F']
[51 'A']
[90 'C']
[98 'A']]