Python 在csv excel文件中对相关数据进行分组

Python 在csv excel文件中对相关数据进行分组,python,regex,grouping,Python,Regex,Grouping,这是一个csv excel文件 Receipt Name Address Date Time Total 25007 A ABC pte ltd 3/7/2016 10:40 12.30 25008 A ABC ptd ltd 3/7/2016 11.30 6.70 25009 B CCC ptd ltd 4/7/2016 07.35 23.40

这是一个csv excel文件

   Receipt Name    Address      Date       Time    Total
    25007   A      ABC pte ltd   3/7/2016   10:40   12.30
    25008   A      ABC ptd ltd   3/7/2016   11.30   6.70
    25009   B      CCC ptd ltd   4/7/2016   07.35   23.40
    25010   A      ABC pte ltd   4/7/2016   12:40   9.90
我如何检索日期和时间并将它们分别分组到A公司和B公司,以使输出类似:(A,2016年3月7日,10:40,11.30,2016年4月7日12:40),(B,2016年4月7日,07:35)

我现有的代码是:

datePattern = re.compile(r"(\d+/\d+/\d+)\s+(\d+:\d+)")  
dateDict =dict()    

for i, line in enumerate(open('sample_data.csv')):
    for match in re.finditer(datePattern,line):
        if match.group(1) in dateDict:
            dateDict[match.group(1)].append(match.group(2))
        else:
            dateDict[match.group(1)] = [match.group(2),]

然而,它只适用于分组日期和时间,但现在我还想将名称作为分组的一部分*最好使用csv模块

使用Pandas模块可以非常轻松地完成:

import pandas as pd

df = pd.read_csv('/path/to/file.csv')

df.groupby(['Name','Date']).Time.apply(list).reset_index().to_csv('d:/temp/out.csv', index=False)
D:\temp\out.csv:

Name,Date,Time
A,3/7/2016,"['10:40', '11.30']"
A,4/7/2016,['12:40']
B,4/7/2016,['07.35']

如果你不想使用熊猫,这是一个可能的解决方案。它不是最优雅的,因为您的csv格式解析起来比较笨拙。如果可以将格式更改为使用非空白字段分隔符,则最好使用适当的csv解析库(如
pandas
或Python内置的
csv
模块)

import re

datePattern = re.compile(r"(\d+/\d+/\d+)\s+(\d+[:.]\d+)")
companyPattern = re.compile(r"^\s+\d+\s+(\w+)")
companyDict = {}

for i, line in enumerate(open('sample_data.csv')):
    # skip csv header
    if i == 0:
        continue

    timestampMatch = datePattern.search(line)
    companyMatch   = companyPattern.search(line)

    # filter out any malformed lines which don't match
    if timestampMatch is None or companyMatch is None:
        continue

    date = timestampMatch.group(1)
    time = timestampMatch.group(2)
    company = companyMatch.group(1)

    companyDict.setdefault(company, []).append("{} {}".format(date, time))
请注意,时间字段使用的小时/分钟分隔符是
还是
,两者不一致,因此我已经考虑到了这一点

在样本数据上运行此命令会为
companyDict
生成以下值:

{'A': ['3/7/2016 10:40', '3/7/2016 11.30', '4/7/2016 12:40'], 'B': ['4/7/2016 07.35']} 

假设您的数据实际上如下所示:

Receipt,Name,Address,Date,Time,Items
25007,A,ABC pte ltd,4/7/2016,10:40,"Cheese, Cookie, Pie"
25008,A,CCC pte ltd,4/7/2016,11:30,"Cheese, Cookie"
25009,B,CCC pte ltd,4/7/2016,07:35,"Chocolate"
25010,A,CCC pte ltd,4/7/2016,12:40," Butter, Cookie"
那么分组就很简单了:

from collections import defaultdict
from csv import reader
with open("test.csv") as f:
    next(f) # skip header
    group_dict = defaultdict(list)
    for _, name, _, dte, time, _ in reader(f):
        group_dict[name].append((dte, time))

from  pprint import pprint as pp

pp(dict(group_dict))
这将给你:

'A': [('4/7/2016', '10:40'), ('4/7/2016', '11:30'), ('4/7/2016', '12:40')],
 'B': [('4/7/2016', '07:35')]}
{('A', '4/7/2016'): ['10:40', '11:30', '12:40'], ('B', '4/7/2016'): ['07:35']}
如果您不想重复日期,则还可以分组:

with open("test.csv") as f:
    next(f) # skip header
    group_dict = defaultdict(list)
    for _, name, _, dte, time, _ in reader(f):
        group_dict[name, dte].append(time)

from  pprint import pprint as pp

pp(dict(group_dict))
这将给你:

'A': [('4/7/2016', '10:40'), ('4/7/2016', '11:30'), ('4/7/2016', '12:40')],
 'B': [('4/7/2016', '07:35')]}
{('A', '4/7/2016'): ['10:40', '11:30', '12:40'], ('B', '4/7/2016'): ['07:35']}

如果我理解正确,您需要从公司名称到时间戳(日期+时间)的字典。在本例中,您希望将公司名称用作字典键。这是对的吗?是的,那是对的。作为字典键的公司名称应包含日期和时间作为其值。为什么要使用正则表达式?您有更好的想法吗?这是我能想到的最好的…想尝试csv模块我对你前面问题的回答告诉你如何使用csv库读取文件,在使用默认命令进行分组之后,我是否必须安装任何显示未找到panda模块的内容。。有其他方法吗?@DarrylDan,是的,熊猫模块必须额外安装。。。是的,有相当多的替代方法很奇怪,当我“打印公司信息”时,它不会打印出任何内容。这可能是因为您的数据与您在其他地方提到的样本中的数据不同。对否决票的人来说,否决票的理由是值得赞赏的。这有一个价值错误:太多的价值无法解包。我假设reader(f):“for u,name,u,dte,time,uu”中的“for u,name,uu,dte,time,uu”有什么问题吗?将数据完全按照您在文件中看到的方式发布,这肯定不是您在问题中看到的方式。对此,我感到抱歉,我可以这样做,因为我的源文件中还有一些字段,我在这里的示例中没有包含这些字段。另一个问题是,如何排除标题,因为它的打印“receive”、“name”等cdid我的上一个解决方案适用于您的上一个问题?这是正确的输出否?或者你只是按日期和姓名分组?