如何根据Python中csv文件中第一列的值分隔行

时间:2015-05-29 11:10:01

标签: python csv

我有一个csv文件。第一列是user_id。

例如:

 User_ID    Latitude    Longitude
1   55.75672775 37.61538506
1   55.75286376 37.62190819
1   47.60760975 -122.334137
1   40.74881754 -73.99116039
2   40.72046126 -74.00974274
2   41.56305944 -70.65380573
2   41.56302733 -70.65389156
2   41.5542606  -70.60093403
2   44.55035619 -69.63040352

我想为每个唯一身份用户运行一些功能。比如说,记录用户拥有的所有位置。 所以我想做一些事情:

For each user_id:
    For row in all the rows of this user:
        Do something
        print user_id, result_output            

我不知道如何实现这个目标。

有人可以帮我这个吗?

3 个答案:

答案 0 :(得分:1)

使用CSV模块中的DictReader组合结果,然后播放:

import csv

data = {}

with open('filepath', 'r') as input:
    reader = csv.DictReader(input)

    for row in reader:
        try:
            data[row['user_id']].append((row['Latitude'], row['Longitude']))
        Except KeyError:
            data[row['User_ID'] = [(row['Latitude'], row['Longitude'])]

for user_id in data:
    # do stuff with your tuples of longs and lats for each user_id

DictReader占据您的第一行并将其用作每列的键。

使用这个我们可以创建一个dict,键作为用户ID,列表作为值。每次遇到user_id时,您只需将longs和lats的元组附加到用户列表。

如果您的分隔符不是逗号,请将delimter参数添加到DictReader。 e.g:

reader = DictReader(file, delimiter='\t')

并确保您使用的密钥正是Python在标头中找到的密钥(可能存在多余的空格,大小写的差异等。)

答案 1 :(得分:0)

也许是这样的(假设你的csv是制表符分隔的)

import csv
import itertools

with open('users.csv') as f:
    reader = csv.DictReader(f, delimiter='\t')

    userdict = {}
    for line in reader:
        uid = int(line['User_ID'])
        if uid not in userdict:
            userdict[uid] = []
        userdict[uid].append({k: float(v) for k,v in line.iteritems() if k != 'User_ID'})

    for k, v in userdict.iteritems():
        print 'User %d has been to' % k
        for loc in v:
           print 'lat=%f long=%f' % (loc['Latitude'], loc['Longitude'])

第一部分创建一个dict,它由用户id(转换为int)键入,值为该用户的所有纬度/经度对的列表(转换为float)。

dict看起来像

{1: [{'Latitude': 55.75672775, 'Longitude': 37.61538506}, {'Latitude': 55.75286376, 'Longitude': 37.62190819}, {'Latitude': 47.60760975, 'Longitude': -122.334137}, {'Latitude': 40.74881754, 'Longitude': -73.99116039}], 2: [{'Latitude': 40.72046126, 'Longitude': -74.00974274}, {'Latitude': 41.56305944, 'Longitude': -70.65380573}, {'Latitude': 41.56302733, 'Longitude': -70.65389156}, {'Latitude': 41.5542606, 'Longitude': -70.60093403}, {'Latitude': 44.55035619, 'Longitude': -69.63040352}]}

使用创建的dict的第二部分打印每个用户去过的所有坐标。所以你得到像

这样的输出
User 1 has been to
lat=55.756728 long=37.615385
lat=55.752864 long=37.621908
lat=47.607610 long=-122.334137
lat=40.748818 long=-73.991160
User 2 has been to
lat=40.720461 long=-74.009743
lat=41.563059 long=-70.653806
lat=41.563027 long=-70.653892
lat=41.554261 long=-70.600934
lat=44.550356 long=-69.630404

您可以通过使用由元组表示的纬度,经度对来节省使用字典。

元组版本(使用defaultdict启动!)

import csv
import itertools
import collections

with open('users.csv') as f:
    reader = csv.DictReader(f, delimiter='\t')

    userdict = collections.defaultdict(list)
    for line in reader:
        userdict[int(line['User_ID'])].append((float(line['Latitude']), float(line['Longitude'])))

    for k, v in userdict.iteritems():
        print 'User %d has been to' % k
        for loc in v:
           print 'Lat=%f Long=%f' % loc

答案 2 :(得分:0)

由于您想要迭代用户ID,您需要事先知道它们是什么 - 这需要提前读取整个文件:

要查找特定用户ID的所有行,您将再次必须再次读取整个文件以将其全部删除。这也意味着您需要多次执行此操作,每个唯一用户ID一次。确保每次迭代都打开文件并正确关闭文件。下面的with语句可确保发生这种情况。

在这里(假设您的csv文件以制表符分隔):

import csv
from collections import defaultdict

filename = 'user_data.csv'

with open(filename, 'rb') as user_data:
    reader = csv.reader(user_data, delimiter='\t')
    next(reader)  # skip header
    user_ids = set(row[0] for row in reader)

for user_id in sorted(user_ids):
    with open(filename, 'rb') as user_data:
        reader = csv.reader(user_data, delimiter='\t')
        next(reader)  # skip header
        for row in (row for row in reader if row[0] == user_id):
            pass  # do something