对于每一天,获取一个非常大的数据帧中两个特定列中匹配的所有行的总和

2024-06-16 08:58:18 发布

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

我有一个非常大的熊猫数据框,有28171643行和4列。该数据帧一天的子集如下所示

我现在的任务是计算每天pair的总金额。天数从90天到320天不等。请注意,(如名称所示)reversed列在每一行中始终包含来自pair列的翻转元组

这里有一个例子:

第0行、第1行、第2行和第4行都包含相同的元组组合,无论它是在pair列还是reversed列中,因此需要求和为5+17+1604+1558=3184。理想情况下,此信息存储在一个新的数据框中,其中包含dayamounttuple列。不管tuple是否包含来自pairreversed的值,因为组合不是定向的

我在下面展示了一个解决方案,但对于这个庞大的数据集来说,这需要花费太长的时间! 作为硬件,我有一个48核186GB RAM的工作站和一个Quadro RTX 8000 GPU。如果有一个简单的解决方案,例如使用Daskrapids.ai这是完全正确的

我每天的缓慢方法:

如果有一种方法可以将其并行化,它也会有所帮助

def analysis(d, t):

    combinations_df = d.loc[d['day'] == t]

    index = []

    for idx, row in combinations_df.iterrows():
        
        idd = combinations_df[combinations_df['reversed'] == row['pair']].index
        
        if len(idd) != 0:
            index.append(idd[0])
        else:
            index.append(-1)

    combinations_df['reversed_idx'] = index

    skippy = []
    to_drop = []
    
    def add_occurences(row):
        if row['reversed_idx'] == -1 or row['reversed_idx'] in skippy:
            return row
        else:
            row['amount'] += combinations_df.loc[row['reversed_idx']]['amount']
            skippy.append(row.name)
            to_drop.append(row['reversed_idx'])
            return row

    res = combinations_df.apply(lambda x: add_occurences(x), axis=1)
    skippy = set(skippy)
    to_drop = list(set(to_drop))
    return res.drop(to_drop)[['day', 'amount', 'pair']]

enter image description here


Tags: to数据dfindexamountdroprowday
2条回答

请考虑将一些示例添加为代码而不是^ {< CD1>},因为这将使您的代码更容易使用。p>

您可以做的是groupby对,然后聚集amount的摘要

如果上表为df,您可以执行以下操作:

>>> df = {'day': [226, 226, 226, 226, 226],
 'amount': [5, 17, 1604, 127, 1558],
 'pair': ['(B2141043,B2161043)',
  '(B2141043,B2161043)',
  '(B2141043,B2161043)',
  '(B2141043,C22D1043)',
  '(B2141043,B2161043)'],
 'reversed': ['(B2161043,B2141043)',
  '(B2161043,B2141043)',
  '(B2161043,B2141043)',
  '(C22D1043,B2141043)',
  '(B2161043,B2141043)']}

>>> df.groupby('pair').agg({'day' : 'first','amount': 'sum'})

                     day  amount
pair
(B2141043,B2161043)  226    3184
(B2141043,C22D1043)  226     127

与前面使用groupby和agg的响应类似,但在唯一键组合上求和:

result = my_df.groupby(['day', my_df.pair.apply(set).apply(tuple)])[['amount']].agg('sum').reset_index()

对于一个5000长度的随机数据帧,使用您的函数在几天内进行循环对我来说需要4.38秒±204毫秒,现在,我是9.86毫秒±185微秒

相关问题 更多 >