通过多重嵌套键对数据进行分组
Grouping data by multiply nested keys
我有一些输入数据:
data = [('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Cond', 'id_1', '56', 10),
('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Cond', 'id_1', '56', 1),
('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Lub', 'id_2', '45', 5),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Cond', 'id_1', '56', 7),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Lub', 'id_2', '45', 3),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Lub', 'id_2', '45', 9)]
行项目是:
(日期, user_id, user_name, user_phone, user_address, product_name, product_id, product_price, product_count)
我应该按 user_id 对数据进行分组,以表示有关每个 UNIQUE 用户的信息,其中 相同产品的数量将被计算在内,使用 python 3 脚本。
像这样:
output_data = [('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, white house', ('Con', 'id_1', '56', 11), ('Lub','id_2', '45', 5)),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'Colorado', ('Con', 'id_1', '56', 7), ('Lub', 'id_2', '45', 12))]
或者您可能会建议一些执行输出数据的更好方法。我将通过机器人将其发送给管理员。
我认为您可以按唯一 ID 对数据进行分组,然后计算乘积总和。基于此输出,您可以轻松创建结构。
import collections
output_data = dict()
for date, user_id, user_name, user_phone, user_address, product_name, product_id, product_price, product_count in data:
if not output_data.get(user_id):
output_data[user_id] = collections.defaultdict(int)
output_data[user_id][product_id] += product_count
print(output_data)
Pandas 风格:
# convert your data to dataframe
df = pd.DataFrame(data, columns=columns)
columns_minus_one = list(df.columns[:-1])
df2 = df.groupby(columns_minus_one , as_index=False).sum('product_count')
输出:
然后你可以得到返回列表:
df2.values.tolist()
您可以使用 itertools.groupby and operator.itemgetter 两次(第一次是按客户分组,第二次是按产品分组)以获得所需的输出。这是代码。
import itertools
import operator
def my_groupby(lst, by_keys, return_keys):
getter = operator.itemgetter(*by_keys)
returner = operator.itemgetter(*return_keys)
# If the data is not sorted, sort it by by_keys to make the groupby work properly
sorted_data = sorted(lst, key=getter)
it = itertools.groupby(sorted_data, key=getter)
for key, subiter in it:
# Yield the key as list and desired columns from the data
yield list(key), [returner(item) for item in subiter]
res = my_groupby(data, by_keys=range(5), return_keys=range(5, 9))
output_data =[]
for customer in res:
prod = list(my_groupby(customer[1], by_keys=range(3), return_keys=[3]))
prod_total = list(map(lambda x: (*x[0], sum(x[1])), prod))
output_data.append(customer[0] + prod_total)
print(output_data)
输出:
[['15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', ('Cond', 'id_1', '56', 11), ('Lub', 'id_2', '45', 5)]
['15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', ('Cond', 'id_1', '56', 7), ('Lub', 'id_2', '45', 12)]]
变量 res
包含按客户详细信息(列号 0 到 5)以及产品详细信息分组的数据。
下一个循环是按产品详细信息分组。 prod
将包含产品详细信息和产品数量。使用 map
函数计算总产品计数。计算结果附加在一个空列表中,output_data
以获得所需的输出。
我有一些输入数据:
data = [('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Cond', 'id_1', '56', 10),
('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Cond', 'id_1', '56', 1),
('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', 'Lub', 'id_2', '45', 5),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Cond', 'id_1', '56', 7),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Lub', 'id_2', '45', 3),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', 'Lub', 'id_2', '45', 9)]
行项目是:
(日期, user_id, user_name, user_phone, user_address, product_name, product_id, product_price, product_count)
我应该按 user_id 对数据进行分组,以表示有关每个 UNIQUE 用户的信息,其中 相同产品的数量将被计算在内,使用 python 3 脚本。
像这样:
output_data = [('15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, white house', ('Con', 'id_1', '56', 11), ('Lub','id_2', '45', 5)),
('15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'Colorado', ('Con', 'id_1', '56', 7), ('Lub', 'id_2', '45', 12))]
或者您可能会建议一些执行输出数据的更好方法。我将通过机器人将其发送给管理员。
我认为您可以按唯一 ID 对数据进行分组,然后计算乘积总和。基于此输出,您可以轻松创建结构。
import collections
output_data = dict()
for date, user_id, user_name, user_phone, user_address, product_name, product_id, product_price, product_count in data:
if not output_data.get(user_id):
output_data[user_id] = collections.defaultdict(int)
output_data[user_id][product_id] += product_count
print(output_data)
Pandas 风格:
# convert your data to dataframe
df = pd.DataFrame(data, columns=columns)
columns_minus_one = list(df.columns[:-1])
df2 = df.groupby(columns_minus_one , as_index=False).sum('product_count')
输出:
然后你可以得到返回列表:
df2.values.tolist()
您可以使用 itertools.groupby and operator.itemgetter 两次(第一次是按客户分组,第二次是按产品分组)以获得所需的输出。这是代码。
import itertools
import operator
def my_groupby(lst, by_keys, return_keys):
getter = operator.itemgetter(*by_keys)
returner = operator.itemgetter(*return_keys)
# If the data is not sorted, sort it by by_keys to make the groupby work properly
sorted_data = sorted(lst, key=getter)
it = itertools.groupby(sorted_data, key=getter)
for key, subiter in it:
# Yield the key as list and desired columns from the data
yield list(key), [returner(item) for item in subiter]
res = my_groupby(data, by_keys=range(5), return_keys=range(5, 9))
output_data =[]
for customer in res:
prod = list(my_groupby(customer[1], by_keys=range(3), return_keys=[3]))
prod_total = list(map(lambda x: (*x[0], sum(x[1])), prod))
output_data.append(customer[0] + prod_total)
print(output_data)
输出:
[['15.05.2022 12:36', 46879, 'Clinton Bill', '555-55-55', 'USA, White House', ('Cond', 'id_1', '56', 11), ('Lub', 'id_2', '45', 5)]
['15.05.2022 13:00', 33990, 'Monika L.', '666-66-66', 'USA, Pennsylvania Av', ('Cond', 'id_1', '56', 7), ('Lub', 'id_2', '45', 12)]]
变量 res
包含按客户详细信息(列号 0 到 5)以及产品详细信息分组的数据。
下一个循环是按产品详细信息分组。 prod
将包含产品详细信息和产品数量。使用 map
函数计算总产品计数。计算结果附加在一个空列表中,output_data
以获得所需的输出。