将一个计数器集合转换为字典

3

我有一个由函数返回的集合结果:

Counter(df.email_address)

它会返回每个电子邮件地址及其重复次数。
Counter({nan: 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1})

我希望你能将它用作字典,并创建一个pandas数据框,其中包含两列,一列为电子邮件地址,另一列为相应的值。我已尝试使用以下代码:
dfr = repeaters.from_dict(repeaters, orient='index')

但我遇到了以下错误:
AttributeError: 'Counter' object has no attribute 'from_dict'

这使得 Counter 看起来并不像一个字典。你有什么想法如何将其附加到 df 中呢?


3
from_dict 是 DataFrame 的类方法,不是字典/计数器的方法。你可以尝试使用:dfr = pd.DataFrame.from_dict(repeaters, orient='index')。该方法将从字典中创建 DataFrame,并将字典的键用作行索引(或列索引,具体取决于 orient 参数的设置) 。 - Alex Riley
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.from_dict.html - Blue Moon
@ajcr,我正想回答那个问题。 - omri_saadon
@omri_saadon:如果您愿意提供答案,请随时提供;评论通常不太有用,所以如果有答案出现,我很乐意删除我的评论。 - Alex Riley
2
计数器是 dict 的子类,可以通过 dict(counter) 将其转换为常规的字典,请参见 https://docs.python.org/3/library/collections.html#collections.Counter。 - user4322779
为什么不直接使用 df.email_address.value_counts() 呢? - EdChum
4个回答

22
d = {}
cnt = Counter(df.email_address)
for key, value in cnt.items():
    d[key] = value

编辑

或者,如@Trif Nefzger建议的:

d = dict(Counter(df.email_address))

2

正如ajcr在评论中所写的那样,from_dict是属于数据帧的方法,因此您可以编写以下内容来实现您的目标:

from collections import Counter
import pandas as pd

repeaters = Counter({"nan": 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1})

dfr = pd.DataFrame.from_dict(repeaters, orient='index')
print dfr

输出:

testorders@worldstores.co.uk     1
nan                           1618
store@kiddicare.com            265

1

不确定为什么有很多复杂的方法。

  1. Counterdict类的子类。因此,您可以将其传递给期望类型为dict的任何内容。
class Counter(dict):
    '''Dict subclass for counting hashable items...
  1. 如果你真的非常想把 Counter 转换成一个 dict
>>> d1 = dict(cntr)
>>> d1
{nan: 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1}
>>> 
>>> 
>>> d2 = {k: v for k, v in cntr.items()}
>>> d2
{nan: 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1}
>>> 

使用pandas.DataFrame.from_dict()Counter创建Pandas DataFrame。它需要一个dict,但可以是以下任一类型的dict:
  • {'col_name1': [r1c1, r2c1...], 'col_name2': [r1c2, r2c2,...], ... 或者
  • {'row_id1': [r1c1, r1c2,...], 'row_id2': [r2c1, r2c2,...], ...

其中rNcM是第N行和第M列的值。

>>> from collections import Counter
>>> cntr = Counter({float('nan'): 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1})
>>> cntr
Counter({nan: 1618, 'store@kiddicare.com': 265, 'testorders@worldstores.co.uk': 1})
>>> 
>>> import panadas as pd
>>> pdf = pd.DataFrame.from_dict({'emails': cntr.keys(), 'repeatation_count': cntr.values()})
>>> print(pdf.to_string())
                         emails  repeatation_count
0                           NaN               1618
1           store@kiddicare.com                265
2  testorders@worldstores.co.uk                  1
>>> 

1

或者你可以使用pd.Series.value_counts,它返回一个Series对象。

df.email_address.value_counts(dropna=False)

样例输出:

b@y.com    2
a@x.com    1
NaN        1
dtype: int64

这不完全是您要求的,但看起来符合您想要实现的目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接