【问题标题】:How to sum rows that start with the same string如何对以相同字符串开头的行求和
【发布时间】:2023-01-29 22:04:09
【问题描述】:

我用 pandas 清理了一个 csv:

import pandas as pd 
import numpy as np
df = pd.read_csv(r'C:\Users\Leo90\Downloads\data-export.csv',encoding='utf-8', header=None, sep='\n')
df = df[0].str.split(',', expand=True)
df=df.iloc[:,[0,1,2,3,4,5,6,7]]
df=df.replace(to_replace='None',value=np.nan).dropna()
df=df.reset_index(drop=True)
columnNames = df.iloc[0] 
df = df[1:] 
df.columns = columnNames
df.groupby('path').head()

处理后的数据如下图

我想用 python 使这个数据框看起来像这样

我知道我可以使用 str.contain 来匹配这些字符串,但它只能返回布尔值,所以我无法对 A 和 B 列求和。这个问题有什么解决办法吗?

我试过 str.contain 来匹配这些字符串,但我无法对 A&B 求和。

【问题讨论】:

标签: python pandas dataframe numpy data-analysis


【解决方案1】:

在起始字符串上使用 groupby.sum

  • 如果起始字符串是固定的,则使用.str[:n] 来分割第一个n 字符

    df = pd.DataFrame({'path': ['google.com/A/123', 'google.com/A/124', 'google.com/A/125', 'google.com/B/3333', 'google.com/C/11111111', 'google.com/C/11111113'], 'A': 1, 'B': 2})
    #                     path  A  B
    # 0       google.com/A/123  1  2
    # 1       google.com/A/124  1  2
    # 2       google.com/A/125  1  2
    # 3      google.com/B/3333  1  2
    # 4  google.com/C/11111111  1  2
    # 5  google.com/C/11111113  1  2
    
    start = df['path'].str[:12]  # first 12 chars of df['path']
    out = df.groupby(start).sum()
    #               A  B
    # path              
    # google.com/A  3  6
    # google.com/B  1  2
    # google.com/C  2  4
    
  • 如果起始字符串是动态的,请使用 .str.extract() 来捕获所需的模式(例如,直到第二个斜杠)

    df = pd.DataFrame({'path': ['A.com/A', 'A.com/A/B/C', 'google.com/A/123', 'google.com/A/124', 'google.com/A/125', 'google.com/B/3333', 'google.com/C/11111111', 'google.com/C/11111113'], 'A': 1, 'B': 2})
    #                     path  A  B
    # 0                A.com/A  1  2
    # 1            A.com/A/B/C  1  2
    # 2       google.com/A/123  1  2
    # 3       google.com/A/124  1  2
    # 4       google.com/A/125  1  2
    # 5      google.com/B/3333  1  2
    # 6  google.com/C/11111111  1  2
    # 7  google.com/C/11111113  1  2
    
    start = df['path'].str.extract(r'^([^/]+/[^/]+)', expand=False)  # up to 2nd slash of df['path']
    out = df.groupby(start).sum()
    #               A  B
    # path              
    # A.com/A       2  4
    # google.com/A  3  6
    # google.com/B  1  2
    # google.com/C  2  4
    

【讨论】:

  • 如果有其他行,比如A.com/A,这个方法可能不行,请问如何解决?谢谢!
  • 因为这种方式需要路径必须有相同的起始字符串
  • @CaihuaFan 你是说A.com/Agoogle.com/A应该放在一起?你只关心/A部分?
  • 因为真正的数据还有很多其他的网页路径,我觉得这个方法只有在前几串路径相同的情况下才有用
【解决方案2】:

按路径分组,同时忽略最终子路径并聚合(求和)其他列。

df['path'] = df["path"].apply(lambda x: "/".join(x.split("/")[:-1]))
df.groupby("path").sum()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-28
    • 2011-03-18
    • 1970-01-01
    • 2021-04-30
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多