簡體   English   中英

列出元素的計數器

[英]List elements’ counter

這里是 Python 的新手。

我正在尋找一種創建列表(輸出)的簡單方法,該方法返回另一個目標列表(MyList)的元素計數,同時保留索引(?)。

這就是我想得到的:

MyList = ["a", "b", "c", "c", "a", "c"]
Output = [ 2 ,  1 ,  3 ,  3 ,  2 ,  3 ]

我找到了類似問題的解決方案。 計算列表中每個元素的出現次數。

In  : Counter(MyList)
Out : Counter({'a': 2, 'b': 1, 'c': 3})

但是,這會返回一個不保留索引的 Counter 對象。

我假設給定計數器中的鍵,我可以構建我想要的輸出,但是我不確定如何繼續。

額外信息,我在腳本中導入了熊貓,而 MyList 實際上是熊貓數據框中的一列。

您可以使用函數itemgetter來代替另一個解決方案中的 listcomp :

from collections import Counter
from operator import itemgetter

lst = ["a", "b", "c", "c", "a", "c"]

c = Counter(lst)
itemgetter(*lst)(c)
# (2, 1, 3, 3, 2, 3)

更新:正如@ALollz 在評論中提到的,這個解決方案似乎是最快速的。 如果 OP 需要列表而不是元組,則結果必須轉換為list

您可以使用list.count方法,將統計的時間每串發生在量MyList 您可以使用列表理解生成包含計數的新列表:

MyList = ["a", "b", "c", "c", "a", "c"]

[MyList.count(i) for i in MyList]
# [2, 1, 3, 3, 2, 3]

使用np.unique創建值計數字典並映射值。 這會很快,但不如 Counter 方法快:

import numpy as np

list(map(dict(zip(*np.unique(MyList, return_counts=True))).get, MyList))
#[2, 1, 3, 3, 2, 3]

中等大小列表的一些時間安排:

MyList = np.random.randint(1, 2000, 5000).tolist()

%timeit [MyList.count(i) for i in MyList]
#413 ms ± 165 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit list(map(dict(zip(*np.unique(MyList, return_counts=True))).get, MyList))
#1.89 ms ± 1.73 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit pd.DataFrame(MyList).groupby(MyList).transform(len)[0].tolist()
#2.18 s ± 12.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

c=Counter(MyList)
%timeit lout=[c[i] for i in MyList]
#679 µs ± 2.33 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

c = Counter(MyList)
%timeit list(itemgetter(*MyList)(c))
#503 µs ± 162 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

更大的列表:

MyList = np.random.randint(1, 2000, 50000).tolist()

%timeit [MyList.count(i) for i in MyList]
#41.2 s ± 5.27 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit list(map(dict(zip(*np.unique(MyList, return_counts=True))).get, MyList))
#18 ms ± 56.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit pd.DataFrame(MyList).groupby(MyList).transform(len)[0].tolist()
#2.44 s ± 12.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

c=Counter(MyList)
%timeit lout=[c[i] for i in MyList]
#6.89 ms ± 22.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

c = Counter(MyList)
%timeit list(itemgetter(*MyList)(c))
#5.27 ms ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

你只需要實現下面的一段代碼

    c=Counter(MyList)
    lout=[c[i] for i in MyList]

現在 list lout是你想要的輸出

熊貓解決方案如下所示:

df = pd.DataFrame(data=["a", "b", "c", "c", "a", "c"], columns=['MyList'])
df['Count'] = df.groupby('MyList')['MyList'].transform(len)

編輯:如果這是您唯一想做的事情,則不應使用熊貓。 我只回答了這個問題,因為熊貓標簽。

性能取決於組的數量:

MyList = np.random.randint(1, 10, 10000).tolist()
df = pd.DataFrame(MyList)

%timeit [MyList.count(i) for i in MyList]
# 1.32 s ± 15.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df.groupby(0)[0].transform(len)
# 3.89 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

MyList = np.random.randint(1, 9000, 10000).tolist()
df = pd.DataFrame(MyList)

%timeit [MyList.count(i) for i in MyList]
# 1.36 s ± 11.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df.groupby(0)[0].transform(len)
# 1.33 s ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

請注意,@Gio 表明列表是熊貓系列對象。 在這種情況下,您可以將 Series 對象轉換為列表:

import pandas as pd

l = ["a", "b", "c", "c", "a", "c"]
ds = pd.Series(l) 
l=ds.tolist()
[l.count(i) for i in ds] 
# [2, 1, 3, 3, 2, 3]

但是,一旦你有了系列,你就可以通過value_counts計算元素。

l = ["a", "b", "c", "c", "a", "c"]
s = pd.Series(l) #Series object
c=s.value_counts() #c is Series again
[c[i] for i in s] 
# [2, 1, 3, 3, 2, 3]

這是來自 hettinger 的經典片段之一:)

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first seen'
     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__,
                            OrderedDict(self))
     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

x = ["a", "b", "c", "c", "a", "c"]
oc = OrderedCounter(x)
>>> oc
OrderedCounter(OrderedDict([('a', 2), ('b', 1), ('c', 3)]))
>>> oc['a']
2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM