gpt4 book ai didi

python - 按时间拆分分组的 Pandas 数据框

转载 作者:行者123 更新时间:2023-12-04 07:23:21 25 4
gpt4 key购买 nike

我需要将我的数据集分成两个部分:80% 和 20%。
我的数据集如下所示:

PersonID    Timestamp   Foo1    Foo2    Foo3    Label
1 1626184812 6 5 2 1
2 616243602 8 5 2 1
2 634551342 4 8 3 1
2 1531905378 3 8 8 1
3 616243602 10 7 8 2
3 634551342 7 5 8 2
4 1626184812 7 9 1 2
4 616243602 5 7 9 1
4 634551342 9 1 6 2
4 1531905378 3 3 3 1
4 768303369 6 1 7 2
5 1626184812 5 7 8 2
5 616243602 6 2 6 1
6 1280851467 3 2 2 2
7 1626184812 10 1 10 1
7 616243602 6 3 6 2
7 1531905378 9 5 7 2
7 634551342 3 7 9 1
8 616243602 8 7 4 2
8 634551342 2 2 4 1
(注意,您应该可以使用 pd.read_clipboard() to get this data into a dataframe 。)
我想要完成的是:
  • 将此数据集拆分为 80/20 拆分(训练、测试)
  • 数据集应该主要由 Timestamp 组织,这意味着旧数据应该在训练中,新数据应该在测试中
  • 此外,不应在培训和测试之间拆分单个人员。例如,给定 PersonID 的所有样本必须在一组或另一组中!

  • 前两点在下面的最小示例中完成。第三点是我遇到的问题。例如,使用 sklearn's train_test_split :
    下面的最小示例:
    # Imports
    import pandas as pd
    from sklearn.model_selection import train_test_split

    # Normal split
    x = pd.read_clipboard()
    train, test = train_test_split(x, train_size=0.8, test_size=0.20, random_state=8)

    # Organizing it by time
    x = pd.read_clipboard()
    x = x.sort_values(by='Timestamp')
    train, test = train_test_split(x, train_size=0.8, test_size=0.20, random_state=8)
    我正在努力弄清楚如何对数据框进行分组,以便一个人不会在训练和测试之间分开。例如,在上面,每个 PersonIDtest数据框也出现在 train 中数据框。如何在确保 PersonID 不被拆分的同时保持比例大致相等?

    最佳答案

    这两个条件很难以严格的方式组合在一起:训练中的旧时间戳与单个 PersonID 训练或测试,但不能同时进行。这里有两个想法。
    对于火车中较旧的时间戳,可能不是最严格的解决方案 ,但您可以尝试获取 max (或 minmean 由您决定)每个 personID 的时间戳和 count ,然后 sort_values最大到 cumsum计数。使用 max 进行拆分训练测试的cumsum乘以你的 80%。

    # calculate the cumsum of count
    s = (
    x.groupby('PersonID')
    ['Timestamp'].agg(['max','count'])
    .sort_values('max')
    ['count'].cumsum()
    )
    s = s<s.max()*0.8 # get boolean mask for train personID
    然后你得到
    train = x.loc[x['PersonID'].isin(s[s].index)]
    print(train)
    # PersonID Timestamp Foo1 Foo2 Foo3 Label
    # 0 1 1626184812 6 5 2 1
    # 1 2 616243602 8 5 2 1
    # 2 2 634551342 4 8 3 1
    # 3 2 1531905378 3 8 8 1
    # 4 3 616243602 10 7 8 2
    # 5 3 634551342 7 5 8 2
    # 6 4 1626184812 7 9 1 2
    # 7 4 616243602 5 7 9 1
    # 8 4 634551342 9 1 6 2
    # 9 4 1531905378 3 3 3 1
    # 10 4 768303369 6 1 7 2
    # 13 6 1280851467 3 2 2 2
    # 18 8 616243602 8 7 4 2
    # 19 8 634551342 2 2 4 1


    test = x.loc[x['PersonID'].isin(s[~s].index)]
    print(test)
    # PersonID Timestamp Foo1 Foo2 Foo3 Label
    # 11 5 1626184812 5 7 8 2
    # 12 5 616243602 6 2 6 1
    # 14 7 1626184812 10 1 10 1
    # 15 7 616243602 6 3 6 2
    # 16 7 1531905378 9 5 7 2
    # 17 7 634551342 3 7 9 1
    另一种选择是使用 sklearn.model_selection.GroupShuffleSplit喜欢:
    from sklearn.model_selection import GroupShuffleSplit

    gss = GroupShuffleSplit(n_splits=1, train_size=.8, random_state=42)

    for train_idx, test_idx in gss.split(x.index, groups=x['PersonID']):
    print("TRAIN ID:", x.loc[train_idx,'PersonID'].unique(),
    ", Timestamp:", x.loc[train_idx,'Timestamp'].mean(),)
    print("TEST ID:", x.loc[test_idx,'PersonID'].unique(),
    ", Timestamp:", x.loc[test_idx,'Timestamp'].mean())
    # TRAIN ID: [1 3 4 5 7 8] , Timestamp: 997267296.9375
    # TEST ID: [2 6] , Timestamp: 1015887947.25
    并增加参数 n_splits并保留为火车提供最小平均值或为测试提供最高平均值的拆分。

    关于python - 按时间拆分分组的 Pandas 数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68365887/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com