Python csv文件的快速排序?

Python csv文件的快速排序?,python,sorting,itertools,Python,Sorting,Itertools,我对python有点陌生,并且主要是为了数据分析而学习python。我有一个CSV文件,看起来是这样(ID,类别): 问题是CSV文件大约有150万个条目。因此,我现在使用izip和csv阅读器加载它们,如下所示: data = izip(csv.reader(open("data.csv", "rb"))) 我在data中有一些条目,我可以简单地使用这些条目进行迭代: for i in data: print i #print i[0][0] # for ids #p

我对python有点陌生,并且主要是为了数据分析而学习python。我有一个CSV文件,看起来是这样(ID,类别):

问题是CSV文件大约有150万个条目。因此,我现在使用izip和csv阅读器加载它们,如下所示:

data = izip(csv.reader(open("data.csv", "rb")))
我在
data
中有一些条目,我可以简单地使用这些条目进行迭代:

for i in data:
    print i
    #print i[0][0] # for ids
    #print i[0][1] # for category
现在,我知道我可以使用if-else/elif构造来检查I[0][1]==5,然后将
I[0][0]
(ID)附加到列表中,但这看起来非常慢,而且我的列表很大

我想知道是否还有其他优雅的方法(可能是使用itertools?)来基于第二列(类别)的值对ID进行bucketize。

既然您说您“主要是为了数据分析而学习python”,那么您肯定应该看看,这样您就可以使用更好的工具集了。(当然,这并不是说从零开始就知道如何构建类似pandas的工具是没有用的。但根据我的经验,即使是使用pandas,你也有足够的机会锻炼你的Python技能,弄清楚如何做一些真实的事情比弄清楚如何重新实现基本功能更有趣。)

您可以使用
read\u csv
将文件读入数据框(如Excel工作表):

>>> import pandas as pd
>>> df = pd.read_csv("group.csv", names=["ID", "category"])
>>> df
          ID  category
0   67512367         0
1      67567         5
2   89789789         5
3  876289347        10
4        638        10
5   98723489        20
6    3828909        20
7   78789789       200
8     978789       200
然后使用
groupby
,为ids建立一个类别字典:

>>> {k: v.tolist() for k,v in df.groupby("category")["ID"]}
{0: [67512367], 200: [78789789, 978789], 10: [876289347, 638], 20: [98723489, 3828909], 5: [67567, 89789789]}
尽管您也可以直接对
groupby
对象执行许多操作(如计算统计等),但老实说,我通常不需要实际的索引列表。更频繁地,我只想“在每个组上执行此操作”,但YMV。

您可以使用:

输出:

['47', '44', '2', '42', '49']
Thu Aug 07 10:55:39 2014    test.profile

         445620949 function calls in 239.002 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
148540313   95.738    0.000  178.467    0.000 csv_test.py:6(<lambda>)
        1   60.535   60.535  239.002  239.002 csv_test.py:2(test)
148540313   55.128    0.000   55.128    0.000 {method 'split' of 'str' objects}
148540313   27.601    0.000   27.601    0.000 {method 'rstrip' of 'str' objects}

        1    0.000    0.000    0.000    0.000 {open}
        1    0.000    0.000  239.002  239.002 <string>:1(<module>)
        5    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects
}
        1    0.000    0.000    0.000    0.000 {method 'keys' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Prof
iler' objects}
这与:

def T(item):
    return item.split(',')[1].rstrip('\n')
要访问这些组,请执行以下操作:

category_name = '42'
bucketized_grouped_keys[category_name]
给分拣员打两次电话

sortedCats = sorted(data, key=attrgetter('category_name'))
sortedIds = sorted(sortedCats, key=attrgetter('id'))

这是因为python中使用的排序算法是,而第二种排序使用第一种排序创建的组来做更少的工作。

请参见-同样的解决方案(
defaultdict(list)
)也可以在这里工作-
{5:[67567,89789789,…],…}
。这非常惊人-以前从未知道过收集。不到一分钟就解决了这个问题。谢谢你这么做。如果你能把这个作为回答,我会接受的。再次感谢!只是指出,您对
izip
的调用实际上对您没有任何帮助。只要把它取下来,它就可以正常工作。谢谢DSM的帮助——我会看看熊猫。你看过约翰沙普斯的评论了吗?在我看来,这似乎是最快的排序方法。思想?@JohnJ:把它叫做一种有点困惑。不过,我不会太担心性能:1.5米的线路非常少,所以任何线性的线路都应该是快速的。您甚至可能被I/O时间所支配,尽管这只是一个猜测。尽管您的解决方案按预期工作,但我喜欢johnrsharpe的建议。基本上,它只有两行:
d=defaultdict(list)
,然后是数据中i的
:d[i[0][1].append(i[0][0])
。d['5']然后将所有的
bucketized
值作为一个整洁的列表提供给我。基本信息如下:
lambda T: T.split(',')[1].rstrip('\n')
def T(item):
    return item.split(',')[1].rstrip('\n')
category_name = '42'
bucketized_grouped_keys[category_name]
sortedCats = sorted(data, key=attrgetter('category_name'))
sortedIds = sorted(sortedCats, key=attrgetter('id'))