每个唯一值采样一条记录(pandas,python)

Posted

技术标签:

【中文标题】每个唯一值采样一条记录(pandas,python)【英文标题】:Sampling one record per unique value (pandas, python) 【发布时间】:2016-11-18 07:37:22 【问题描述】:

我使用 python-pandas 数据框,并且我有一个包含用户及其数据的大型数据框。每个用户可以有多个行。我想为每个用户采样 1 行。 我目前的解决方案似乎效率不高:

df1 = pd.DataFrame('User': ['user1', 'user1', 'user2', 'user3', 'user2', 'user3'],
                 'B': ['B', 'B1', 'B2', 'B3','B4','B5'],
                 'C': ['C', 'C1', 'C2', 'C3','C4','C5'],
                 'D': ['D', 'D1', 'D2', 'D3','D4','D5'],
                 'E': ['E', 'E1', 'E2', 'E3','E4','E5'],
                 index=[0, 1, 2, 3,4,5])

df1
>>  B   C   D   E   User
0   B   C   D   E   user1
1   B1  C1  D1  E1  user1
2   B2  C2  D2  E2  user2
3   B3  C3  D3  E3  user3
4   B4  C4  D4  E4  user2
5   B5  C5  D5  E5  user3

userList = list(df1.User.unique())
userList
> ['user1', 'user2', 'user3']

I 循环遍历唯一用户列表并为每个用户采样一行,将它们保存到不同的数据框

usersSample = pd.DataFrame() # empty dataframe, to save samples
for i in userList:
    usersSample=usersSample.append(df1[df1.User == i].sample(1)) 

> usersSample   
B   C   D   E   User
0   B   C   D   E   user1
4   B4  C4  D4  E4  user2
3   B3  C3  D3  E3  user3

有没有更有效的方法来实现这一目标?我真的很想: 1) 避免附加到数据框 usersSample。这是一个逐渐增长的对象,它严重影响了性能。 2)避免一次循环一个用户。有没有办法更有效地对每个用户进行 1 次采样?

【问题讨论】:

【参考方案1】:

这就是你想要的:

df1.groupby('User').apply(lambda df: df.sample(1))

没有额外的索引:

df1.groupby('User', group_keys=False).apply(lambda df: df.sample(1))

【讨论】:

如果顺序相关,我们可以使用lambda df: df.head(1) 来获取第一个值。【参考方案2】:
df1_user_sample_one = df1.groupby('User').apply(lambda x:x.sample(1)) 

使用DataFrame.groupby.apply和lambda函数对1进行采样

【讨论】:

【参考方案3】:

根据每个用户的行数,这可能会更快:

df.sample(frac=1).drop_duplicates(['User'])

【讨论】:

这在df1 上更快。 pd.concat([df for _ in range(100000)]) 速度较慢 @piRSquared 我在更大的数据集上尝试过,但用户列的类型是整数(117ms vs 3.96s),但是当类型是对象时,它似乎总是更慢。 @piRSquared 对不起,区别来自用户数量。在这个例子中,用户数量非常少。 df= pd.DataFrame('user' + pd.Series(np.random.choice(range(1000), (1000000))).astype(str), columns=['User']) 你是 358 毫秒,我是 4.22 秒。【参考方案4】:

.drop_duplicates 应该可以正常工作:

df1.drop_duplicates(subset='User')

这将保留“用户”列中每个第一次出现的值并返回相应的行。

【讨论】:

这将保留每个第一次出现的值 不是关于样本的问题吗?

以上是关于每个唯一值采样一条记录(pandas,python)的主要内容,如果未能解决你的问题,请参考以下文章

pandas df中多列的唯一记录计数

我们如何在列的每个值中对 pandas 数据框进行二次采样

为dataframe python列中的每个唯一值创建excel工作表

Python / Pandas合并并从逗号分隔的变量/列生成唯一值列表[重复]

根据 HIVE 表中的时间戳确定每个唯一值的采样间隔

Pandas,对于一列中的每个唯一值,在另一列中获取唯一值