Python 字典中的分组数据

Python 字典中的分组数据,python,dictionary,pandas,Python,Dictionary,Pandas,我的数据如下所示: object weight table 2.3 chair 1.2 chair 1.0 table 1.5 drawer 1.8 table 1.7 object counter weight table 3 2.3, 1.5, 1.7 chair 2 1.2, 1.0 drawer 1 1.8 我想根据不同类型的对象对

我的数据如下所示:

object   weight
table     2.3
chair     1.2
chair     1.0
table     1.5
drawer    1.8
table     1.7
object     counter     weight
table         3        2.3, 1.5, 1.7
chair         2        1.2, 1.0
drawer        1        1.8
我想根据不同类型的
对象对数据进行分组。另外,我想知道我有多少个物体和它们的重量

例如,我的最终数据应该如下所示:

object   weight
table     2.3
chair     1.2
chair     1.0
table     1.5
drawer    1.8
table     1.7
object     counter     weight
table         3        2.3, 1.5, 1.7
chair         2        1.2, 1.0
drawer        1        1.8
以下是我的尝试:

data = pd.read_csv('data.dat', sep = '\s+')

grouped_data = {'object':[],'counter':[], 'weight':[]}
objects = ['table', 'chair', 'drawer']

for item in objects:
    counter = 0
    weight = []
    grouped_objects['object'].append(item)
    for i in range(len(data)):
        if item == data['name'][i]:
            counter += 1
            grouped_data['weight'].append(data['weight'])
            grouped_data['counter'].append(counter)

它没有给我想要的输出。有什么建议吗?

您可以通过使用
agg
并传递函数列表来执行此操作:

In [32]:
def counter(x):
    return len(x)
​
def weight(x):
    return ', '.join(x)
​
df.groupby('object')['weight'].agg([weight, counter]).reset_index()

Out[32]:
   object         weight  counter
0   chair       1.2, 1.0        2
1  drawer            1.8        1
2   table  2.3, 1.5, 1.7        3

这假定
weight
dtype
已经是
str
,如果不是,那么通过执行
df['weight']=df['weight']转换。astype(str)

我认为您实际上想要的是一个
defaultdict
(它是集合库中的一个类),其默认函数返回空列表。然后,该列表的
len
将为您提供计数器。例如:

from collections import defaultdict
grouped_data = defaultdict(list)

for i in range(data):
    name, weight = data['name'][i], data['weight'][i]
    grouped_data[name].append(weight)

print len(grouped_data['table']) #should return count of weights
使用agg:

df.groupby("object")["weight"].agg({"counter": "count", "weight": lambda x: ", ".join(x.astype(str))})
Out[57]: 
        counter         weight
object                        
chair         2       1.2, 1.0
drawer        1            1.8
table         3  2.3, 1.5, 1.7

您只需使用
len()
,即可获得计数,并且您可以使用
for item in data
直接迭代数据,而不是使用
range
获取索引:

data = [
    { 'name': 'table', 'weight': 2.3 },
    { 'name': 'chair', 'weight': 1.2 },
    { 'name': 'chair', 'weight': 1.0 },
    { 'name': 'table', 'weight': 1.5 },
    { 'name': 'drawer', 'weight': 1.8 },
    { 'name': 'table', 'weight': 1.7 }
]

grouped_data = {'table': [], 'chair': [], 'drawer': []}

for item in data:
    grouped_data[item['name']].append(item['weight'])

print(grouped_data)
print(len(grouped_data['table']))

>>> {'table': [2.3, 1.5, 1.7], 'chair': [1.2, 1.0], 'drawer': [1.8]}
>>> 3

我一眼就能看出几个潜在的错误:

  • len(data)
    不会给出数据中的行数,而是列数。尝试改用
    data.shape[1]
  • 将所有种类的权重添加到权重列表中,而不是为每种类型创建一个列表
  • 每次添加的不是一个权重,而是整个权重列
无论如何,我会用另一种方式,但也会用字典。字典中每个条目的键都是对象的类型,值是要存储的数据,这是有道理的。例如,
{'table':{'counter':3,weight:[2.3,1.5,1.7]}

现在,您只需循环浏览数据,填写字典,然后以您想要的任何格式打印它。此方法也应该更有效(n而不是n^2):


希望它对您有用:)

您可以将groupby与词典一起使用

>>> pd.DataFrame({col: [len(group), group.loc[:, 'weight'].tolist()] 
                  for col, group in df.groupby('object')}).T.rename(columns={0: 'count', 
                                                                             1: 'weights'})

       count          weights
chair      2       [1.2, 1.0]
drawer     1            [1.8]
table      3  [2.3, 1.5, 1.7]