将 collections.Counters 的组合频率从数据帧多索引转换为字符串
Posted
技术标签:
【中文标题】将 collections.Counters 的组合频率从数据帧多索引转换为字符串【英文标题】:Converting collections.Counters of combinations frequency from dataframe multi-index into string 【发布时间】:2021-07-09 16:12:54 【问题描述】:想请教一些关于如何正确执行此操作的建议。我是 python 新手。
最初我想找出多索引组合的计数器/频率。我尝试了几种方法,例如循环、itertuples、iterrows 等,我意识到最快和最少开销是使用 collections.Counter
但是,它返回多索引索引组合的元组列表作为计数器字典键。元组的键使得后续处理变得困难。
因此,我正在研究如何将它们变成带有分隔符的字符串,以便之后的处理更易于管理。
例如下面这个多索引:
# testing
def testing():
testing_df = pd.read_csv("data/testing.csv", float_precision="high")
testing_df = testing_df.set_index(["class", "table", "seat"]).sort_index()
print("\n1: \n" + str(testing_df.to_string()))
print("\n2 test: \n" + str(testing_df.index))
occurrences = collections.Counter(testing_df.index)
print("\n3: \n" + str(occurrences))
输出:
1:
random_no
class table seat
Emerald 1 0 55.00
Ruby 0 0 33.67
0 24.01
1 87.00
Topaz 0 0 67.00
2 test:
MultiIndex([('Emerald', 1, 0),
( 'Ruby', 0, 0),
( 'Ruby', 0, 0),
( 'Ruby', 0, 1),
( 'Topaz', 0, 0)],
names=['class', 'table', 'seat'])
3:
Counter(('Ruby', 0, 0): 2, ('Emerald', 1, 0): 1, ('Ruby', 0, 1): 1, ('Topaz', 0, 0): 1)
从3)我们可以看出,它返回不同数据类型的元组中的组合作为dict键,处理起来很困难。
我尝试将它分开或使其成为字符串,以便处理它更容易。
尝试以下错误:
x = "|".join(testing_df.index)
print(x)
x = "|".join(testing_df.index)
TypeError: sequence item 0: expected str instance, tuple found
以下有错误
x = "|".join(testing_df.index[0])
print(x)
x = "|".join(testing_df.index[0])
TypeError: sequence item 1: expected str instance, numpy.int64 found
基本上,它是:
-
我在计算 collections.Counter 或之前将组合变成字符串
将其制成 collections.Counter 后,其中所有众多键都是元组并将这些键转换为字符串
请问我该如何正确执行此操作?
非常感谢!
【问题讨论】:
【参考方案1】:我可以为2.提供一个解决方案,将键元组转换为字符串:
from collections import Counter
# recreate your problem
occurrences = Counter([('Ruby', 0, 0),
('Ruby', 0, 0),
('Emerald', 1, 0),
('Ruby', 0, 1),
('Topaz', 0, 0)])
# convert tuple keys to string keys
new_occurrences = '|'.join(str(index) for index in key) : value for key,value in occurrences.items()
print(new_occurrences)
'Ruby|0|0': 2, 'Emerald|1|0': 1, 'Ruby|0|1': 1, 'Topaz|0|0': 1
Counter
是dict
的子类,因此您可以使用 dict-comprehensions 和 .items()
等花哨的东西同时循环键和值。
根据您打算如何进一步处理数据,将计数器的结果转换为pandas
DataFrame 可能更有用。仅仅是因为pandas
提供了更多更简单的处理功能。
方法如下:
import pandas as pd
df = pd.DataFrame('class': [k[0] for k in occurrences.keys()],
'table': [k[1] for k in occurrences.keys()],
'seat': [k[2] for k in occurrences.keys()],
'counts': [v for _,v in occurrences.items()])
df.head()
class table seat counts
0 Ruby 0 0 2
1 Emerald 1 0 1
2 Ruby 0 1 1
3 Topaz 0 0 1
【讨论】:
以上是关于将 collections.Counters 的组合频率从数据帧多索引转换为字符串的主要内容,如果未能解决你的问题,请参考以下文章