在熊猫中洗牌但有序
Posted
技术标签:
【中文标题】在熊猫中洗牌但有序【英文标题】:Shuffling rows in pandas but orderly 【发布时间】:2020-09-25 09:47:29 【问题描述】:假设我有一个包含三列的数据框:年龄、性别和国家。
我想根据性别随机打乱这些数据但以有序的方式。有 n 个男性和 m 个女性,其中 n 可以小于、大于或等于 m。改组应该以这样一种方式发生,即我们得到 8 人大小的以下结果:
男,女,男,女,男,女,女,女,....(如果有更多的女性:m > n) 男性,女性,男性,女性,男性,男性,男性,男性(如果有更多男性:n > m) 男,女,男,女,男,女,男,女,男,女(如果男女相等:n = m)
df = pd.DataFrame('Age': [10, 20, 30, 40, 50, 60, 70, 80],
'Gender': ["Male", "Male", "Male", "Female", "Female", "Male", "Female", "Female"],
'Country': ["US", "UK", "China", "Canada", "US", "UK", "China", "Brazil"])
【问题讨论】:
随机但有序的话相互矛盾。 【参考方案1】:首先添加每个组内的序号:
df['Order'] = df.groupby('Gender').cumcount()
然后排序:
df.sort_values('Order')
它给你:
Age Gender Country Order
0 10 Male US 0
3 40 Female Canada 0
1 20 Male UK 1
4 50 Female US 1
2 30 Male China 2
6 70 Female China 2
5 60 Male UK 3
7 80 Female Brazil 3
如果您想随机播放,请从一开始就这样做,例如df = df.sample(frac=1)
,见:Shuffle DataFrame rows
【讨论】:
我总是忘记.cumcount()
,这是一个非常有用的功能。不错。
亲爱的约翰,非常感谢您的策略!有用!使我免于编写带有大量 if/else 条件的 for 循环代码。最重要的是用生奶油,我可以建议大卫修改你的原始代码:sort_values(['Sort_Column', 'Gender'], ascending=[True,False])
【参考方案2】:
使用'Sort_Column'
创建两个新数据帧,并使df_male
数据帧为偶数值,df_female
数据帧为奇数值。然后,使用pd.concat
将它们重新组合在一起,并在'Sort_Column'
上使用.sort_values()
。
df = pd.DataFrame('Age': [10, 20, 30, 40, 50, 60, 70, 80],
'Gender': ["Male", "Male", "Male", "Female", "Female", "Male", "Female", "Female"],
'Country': ["US", "UK", "China", "Canada", "US", "UK", "China", "Brazil"])
df['Sort_Column'] = 0
df_male = df.loc[df['Gender'] == 'Male'].reset_index(drop=True)
df_male['Sort_Column'] = df_male['Sort_Column'] + df_male.index*2
df_female = df1.loc[df1['Gender'] == 'Female'].reset_index(drop=True)
df_female['Sort_Column'] = df_female['Sort_Column'] + df_female.index*2 + 1
df_sorted=pd.concat([df_male, df_female]).sort_values('Sort_Column').drop('Sort_Column', axis=1).reset_index(drop=True)
df_sorted
输出:
Age Gender Country
0 10 Male US
1 40 Female Canada
2 20 Male UK
3 50 Female US
4 30 Male China
5 70 Female China
6 60 Male UK
7 80 Female Brazil
【讨论】:
@John Zwinck 感谢您的解决方案!非常聪明,我必须说。但是当两个性别的 cumcount 相同时,它就会遇到问题。然后 F->M->F->M 的顺序中断。这是订单中断的示例。一旦他们有共同的指数,性别就不会在男性和女性之间不断切换。你建议我们如何解决这个问题? link 我认为你回答错了:),但你可以这样做:.sort_values(['Sort_Column', 'Gender'], ascending=[True,False])
亲爱的大卫,我的错!非常感谢您的帮助!这就是我喜欢问题解决者社区的原因!我们共同提出最佳解决方案。 :)以上是关于在熊猫中洗牌但有序的主要内容,如果未能解决你的问题,请参考以下文章