快速应用怪异的选通技术

2024-09-29 01:20:58 发布

您现在位置:Python中文网/ 问答频道 /正文

对于一系列奇怪的数据处理问题中的另一个,我有一个数据框,看起来像这样:

                 id        tof
0              10.0  2004847.0
1              10.0  2066116.0
2              10.0  5441996.0
3              10.0  5642443.0
4              15.0  1979815.0
5              15.0  1992399.0
6              15.0  2008208.0
7              15.0  2098060.0
8              15.0  3980280.0
9              27.0  2027878.0
10             27.0  2047992.0
11             27.0  5308106.0
12             27.0  6743403.0

我想在数据上应用一个按ID分组的门,我只想保留这样的数据:tof和一系列的数字相加,而差值是一系列数字之间的差值。你知道吗

例如,我将有tof_sum = [7000000,80000000]tof_dif = [3000000,3500000],门将保留行02,因为它们的和在上面的数字之间,它们的差也是一样。它还将保留第1行,因为它与第2行有关系。但是,它不会保留任何id为15的行,因为没有两行的总和超过7000000。你知道吗

我可以想象

a = pd.DataFrame([[k, c0, c1] for k, tof in Da.groupby('id').tof
                              for c0, c1 in combinations(tof, 2)
                                ], columns=['id', 'tof0', 'tof1'])

它为每个id成对生成所有组合,然后像这样比较它们:

      id       tof0       tof1
0   10.0  2004847.0  2066116.0 (sum not bigger than 7000000, next)
1   10.0  2004847.0  5441996.0 (this sum is in range, difference is in range, ✓)
2   10.0  2004847.0  5642443.0 (sum and difference are in range here too, ✓ )
3   10.0  2066116.0  5441996.0 (etc, etc)
4   10.0  2066116.0  5642443.0
5   10.0  5441996.0  5642443.0
6   15.0  1979815.0  1992399.0
7   15.0  1979815.0  2008208.0
8   15.0  1979815.0  2098060.0
9   15.0  1979815.0  3980280.0
10  15.0  1992399.0  2008208.0
11  15.0  1992399.0  2098060.0
12  15.0  1992399.0  3980280.0
13  15.0  2008208.0  2098060.0
14  15.0  2008208.0  3980280.0
15  15.0  2098060.0  3980280.0
16  27.0  2027878.0  2047992.0
17  27.0  2027878.0  5308106.0
18  27.0  2027878.0  6743403.0
19  27.0  2047992.0  5308106.0
20  27.0  2047992.0  6743403.0
21  27.0  5308106.0  6743403.0

每次满足和差在各自范围内的条件时,它都会用这些tof保存行

但是对于我要处理的数百万行数据文件来说,这个命令花费了惊人的长时间(比如几分钟)。你知道吗

有什么想法吗?你知道吗


Tags: 数据inidforisrange数字sum
1条回答
网友
1楼 · 发布于 2024-09-29 01:20:58

正如评论中提到的,处理数百万行数据的几分钟时间并不长。您可以通过广播将过程矢量化:

def get_pairs(g):
    x = g.tof.values

    # upper triangle matrix to avoid duplicate pairs: (a,b) and (b,a)
    uniques = np.arange(len(x)) > np.arange(len(x))[:, None]

    sums = x + x[:, None]
    sum_mask = (sums>7000000) & (sums<80000000)

    diffs = np.abs(x - x[:, None])
    diff_mask = (diffs > 3000000) & (diffs < 3500000)

    mask = sum_mask & diff_mask & uniques

    ret_df = pd.DataFrame(mask, index=x, columns=x)
    ret_df = ret_df.stack()
    return ret_df[ret_df]

那么

new_df = df.groupby('id').apply(get_pairs).reset_index().drop(0, axis=1)

输出:

     id    level_1    level_2
0  10.0  2004847.0  5441996.0
1  10.0  2066116.0  5441996.0
2  27.0  2027878.0  5308106.0
3  27.0  2047992.0  5308106.0

稍加修改即可获得行的索引,您可以使用这些索引来过滤原始数据:

def get_pairs(g):
    x = g.tof.values

    # upper triangle matrix
    uniques = np.arange(len(x)) > np.arange(len(x))[:, None]

    sums = x + x[:, None]
    sum_mask = (sums>7000000) & (sums<80000000)

    diffs = np.abs(x - x[:, None])
    diff_mask = (diffs > 3000000) & (diffs < 3500000)

    mask = sum_mask & diff_mask & uniques

    # note the different columns and index.
    ret_df = pd.DataFrame(mask, index=g.index, columns=g.index)
    ret_df = ret_df.stack()
    return ret_df[ret_df]

输出:

     id  level_1  level_2
0  10.0        0        2
1  10.0        1        2
2  27.0        9       11
3  27.0       10       11

相关问题 更多 >