我有一个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
我不知道如何实现这个目标。
有人可以帮我这个吗?
答案 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