【问题标题】:Python - Compressing collection of TO and FROM value ranges across rows in a dataframePython - 压缩数据帧中跨行的 TO 和 FROM 值范围的集合
【发布时间】:2021-02-21 07:34:25
【问题描述】:

我有一个包含以下内容的数据框。对于每个组,您会看到以一组从/到列的形式表示的重复“范围”(即 value_x_low 到 value_x_high)。

例如,40000 到 50000 反映为 value_1、GROUP1、前 3 条记录的 'from' 和 'to' 范围;而第 4 条记录的“从”和“到”范围为 60000 到 70000。继续,在为 value_1 建立的 40000 到 50000 范围内,000 到 ZZZ 在 value_2 低/高字段中重复两次,等等。

group value_1_low value_1_high value_2_low value_2_high value_3_low value_3_high
GROUP1 40000 50000 000 ZZZ 123 123
GROUP1 40000 50000 000 ZZZ 456 456
GROUP1 40000 50000 ABC ABC 789 789
GROUP1 60000 70000 000 ZZZ 000 999
GROUP2 40000 50000 000 ZZZ 123 123
GROUP2 40000 50000 000 ZZZ 456 456
GROUP2 40000 50000 000 ZZZ 789 789
GROUP2 40000 50000 000 ZZZ 012 012

本质上,我试图通过在从 value_1 遍历到 value_2 再到 value_3 等时删除重复值来压缩上面的表格......下面是符合预期的输出(我基本上已经构建了潜在样本输出为嵌套字典,其中每个范围都表示为一个元组)。

{'GROUP1': {(40000, 50000): {(000, ZZZ): [(123, 123), (456, 456)], ('ABC', 'ABC'): [(789, 789)]},
           {(60000, 70000): {(000, ZZZ): [(000, 999)]}},
 'GROUP2': {(40000, 50000): {(000, ZZZ): [(123, 123), (456, 456), (789, 789), (012, 012)]}}} 

我尝试在下面使用字典理解;但是,我正在努力在额外的“groupbys”中分层。

grouped_dict = {k: f.groupby(['value_1_low', 'value_1_high'])['value_2_low', 
                                                              'value_2_high', 
                                                              'value_3_low', 
                                                              'value_3_high'].apply(lambda g: g.value.tolist()).to_dict()
for k, f in group_dataframe.groupby('group')}

另外,我想知道是否已经有一个包可以优化这种压缩。因为在某些情况下,最初按 value_1_low/value_1_high 分组可能不会返回最压缩的结果。

这是我的第一篇文章....所以,如果我遵守了格式/等,请告诉我。要求。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    为了更容易操作字典,首先创建将用作所需字典键的元组。使用 applyaxis=1 访问每一行并获取每个 value_X 对的低值和高值。使用groupby(["g", "v1", "v2"]) 创建组,留下将用于创建元组列表的v3

    遍历每个创建的组,对于每个组,使用setdefault 和组名作为参数。如果键在字典中,setdefault 将返回该键的值,如果不是,则使用函数第二个参数中的值插入键。作为最后一步,您可以将v3 列作为list 分配给字典。

    如果您想在输出字典中保留前导零,例如元组 [0, 999]....(789, 789), (12, 12)] 最初是 [000, 999]012,则必须将数据转换为字符串 (@987654335 @)。

    import pandas as pd
    
    df = pd.read_csv("sample.csv", sep="\s+")
    print(df)
    
    do = pd.DataFrame()
    do["g"] = df.group
    do["v1"] = df.apply(lambda x: (x.value_1_low, x.value_1_high), axis=1)
    do["v2"] = df.apply(lambda x: (x.value_2_low, x.value_2_high), axis=1)
    do["v3"] = df.apply(lambda x: (x.value_3_low, x.value_3_high), axis=1)
    
    df_group = do.groupby(["g", "v1", "v2"])
    
    d_out = {}
    for gn, gv in df_group:
        d1 = d_out.setdefault(gn[0], {gn[1]: {}})
        d2 = d1.setdefault(gn[1], {gn[2]: {}})
        d2[gn[2]] = gv.v3.to_list()
    
    print(d_out)
    

    d_out的输出

    {
        "GROUP1": {
            (40000, 50000): {
                ("000", "ZZZ"): [(123, 123), (456, 456)],
                ("ABC", "ABC"): [(789, 789)],
            },
            (60000, 70000): {("000", "ZZZ"): [(0, 999)]},
        },
        "GROUP2": {
            (40000, 50000): {("000", "ZZZ"): [(123, 123), (456, 456), (789, 789), (12, 12)]}
        },
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-07
      • 2012-07-14
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多