在Python

时间:2018-02-27 21:44:18

标签: python aggregation

我有一个像这样的CSV文件:

route|id|alias|longitude|latitude
A|1|first|-33.51808226|-70.58256582
A|1|first|-33.52850414|-70.57645648
B|2|second|-33.51952529|-70.58043875
B|2|second|-33.53452223|-70.58343824

每条路线的idalias对于相同的route始终相同。此外,每个route都有一组points,每个longitudelatitudepoints组成。我正在尝试按routeitertools groupby进行分组,但我希望生成文件的每个字段。

当我使用routeroute分组时,我只能获得pointswith open(self.datafile, "r") as f: reader = csv.DictReader(f, delimiter='|') # Group data using 'route' as key for route, points in groupby(reader, lambda p: p['route']): points = list(points) points = [ { 'longitude': p['longitude'], 'latitude': p['latitude'] } for p in points ] yield { "_source": { "route": route, "points": points } }

id

我尝试了不同的方法来获取alias的{​​{1}}和route(例如使用route['id']p['id']获取id或者在现有的之外使用另一个),但它们都没有奏效。

使用groupby时是否有办法获得复合键?或者也许是解决我问题的更简单方法?

我希望能够得到这个:

yield {
                "_source": {
                    "route": route,
                    "id": id,
                    "alias": alias,
                    "points": points
                }
            }

2 个答案:

答案 0 :(得分:4)

您确实可以groupby使用复合键:

# Group data using 'route', 'id', 'alias' as key
for route_id_alias, values in itertools.groupby(reader, lambda p: (p['route'], p['id'], p['alias'])):
    points = [
        {
            'longitude': p['longitude'],
            'latitude': p['latitude'],
        } for p in values
    ]
    print( {
        "_source": {
            "route": route_id_alias[0],
            "id": route_id_alias[1],
            "alias": route_id_alias[2],
            "points": points,
        }
    })

您只需要在产生结果时按索引访问密钥。

Try it online!

答案 1 :(得分:0)

如果您从groupby函数返回元组,则可以一次key个多个字段。

您可以使用operator.itemgetter。 for循环看起来像:

for (route, id, alias), points in groupby(reader, key=operator.itemgetter('route', 'id', 'alias')):