Python 在csv excel文件中对相关数据进行分组
这是一个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
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我的上一个解决方案适用于您的上一个问题?这是正确的输出否?或者你只是按日期和姓名分组?