【问题标题】:Split a CSV file into two equal size groups having a criteria将 CSV 文件拆分为具有条件的两个大小相等的组
【发布时间】:2020-04-19 17:01:39
【问题描述】:

关于这个有很多类似的问题,但没有一个与我的问题相近。

我想将一个 csv 数据分成两组长度相等、条件相同的组,这里是年龄。此外,更难的问题可能是结合多个抽样标准,这可能是年龄 && 工作经验 && 管理经验,因此结果尽可能标准化。

我知道这是一个 NP(或更复杂的复杂性)的优化问题,也许不会有封闭形式或明确的答案,但足够接近会很好。

import random
import csv
import numpy as np
import pandas as pd

classlist = pd.read_csv('Classlist-Test.csv')
df = pd.DataFrame(classlist)
grouped = df.groupby(['Age'])

grouped.sum()
     Work Experience (Yrs)  Management Experience (Yrs)
Age
23                       1                            1
24                      14                            2
25                      15                            8
26                      42                           10
27                      44                            5
28                      30                            8
29                      21                            3
30                      19                            6
31                      44                           12
32                      37                            5
33                      31                            9
34                      21                           12
35                      18                            1
36                      24                            0
38                      21                            4
39                      35                           16
40                      28                           18
41                      15                            7
45                      49                           17
46                      20                           11
53                      25                           10

>>> df.mean()
Age                            30.158879
Work Experience (Yrs)           5.177570
Management Experience (Yrs)     1.542056
dtype: float64
>>> df.median()
Age                            28.0
Work Experience (Yrs)           4.0
Management Experience (Yrs)     0.0
dtype: float64
>>> df.std()
Age                            5.557843
Work Experience (Yrs)          4.580132
Management Experience (Yrs)    2.533848
dtype: float64

关于如何在 Python 中做到这一点有什么建议吗?有没有一种抽样方法可以做到这一点? 谢谢

【问题讨论】:

  • 我认为优化在这里不是一个好的选择。您想查看最近的邻居和配对匹配方法。你可以在网上找到很多关于这个的。
  • 计算 Age 的 cumsum 并确定 50% 的值,然后将该值的数据集分成两组。有了更多标准,这也可以类似地工作。
  • @JanChristophTerasa,这似乎是 50% 的百分位数,但同样,如果我将其拆分,我将有两个班级,一个高于平均水平,另一个平均水平较低。我希望两者最终都具有相同的平均值。
  • 一般来说,不可能确保两个组的均值相同。

标签: python pandas group-by split


【解决方案1】:

我建议将train_test_splitstratify 选项一起使用,并将test_size 设为0.5,如下所示:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

np.random.seed(123)
df = pd.DataFrame({"Age": np.random.randint(0,50,10000),
                   "work_exp" : np.random.randint(0,3,10000),
                   "man_exp" : np.random.randint(0,3,10000),
                   "value": np.random.randint(0,2,10000)})
df_train, df_test = train_test_split(df, test_size=0.5, 
                                     stratify=df[["Age", "work_exp", "man_exp"]], random_state=0)

这是df_traindf_test的主要统计结果:

> df_train.describe()
              Age     work_exp     man_exp        value
count  5000.000000  5000.000000  5000.00000  5000.000000
mean     24.516600     1.014200     1.01520     0.493400
std      14.453107     0.820812     0.81431     0.500006
min       0.000000     0.000000     0.00000     0.000000
25%      12.000000     0.000000     0.00000     0.000000
50%      24.000000     1.000000     1.00000     0.000000
75%      37.000000     2.000000     2.00000     1.000000
max      49.000000     2.000000     2.00000     1.000000
> df_test.describe()
              Age     work_exp      man_exp       value
count  5000.00000  5000.000000  5000.000000  5000.00000
mean     24.47900     1.011200     1.009400     0.51000
std      14.45663     0.819762     0.815503     0.49995
min       0.00000     0.000000     0.000000     0.00000
25%      12.00000     0.000000     0.000000     0.00000
50%      24.00000     1.000000     1.000000     1.00000
75%      37.00000     2.000000     2.000000     1.00000
max      49.00000     2.000000     2.000000     1.00000

希望对你有帮助

【讨论】:

  • 感谢@Raphaele,但这种方法使用的是随机 iid 数据,分布是正常的。我们可以根据我自己的数据来假设吗?
  • train_test_splitstratify 选项依赖于StratifyShuffleSplit 的源代码。在stratify 参数中放置几个​​变量相当于说一个类是这些变量(年龄、经验、人。经验)的唯一组合,并且将在此分类变量上进行分层。分层旨在使两个样本中该分类变量的比例相同。因此,如果某个班级只有一个成员(例如,如果您只有一行用于年龄、经验和管理经验的特定组合),则它不会起作用。
  • 很好的答案,谢谢@Raphaele
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 2011-01-02
  • 2019-06-14
  • 2020-03-22
  • 2021-01-02
  • 1970-01-01
相关资源
最近更新 更多