如何循环分组的 Pandas 数据框?
- 2025-02-28 08:23:00
- admin 原创
- 61
问题描述:
数据框:
c_os_family_ss c_os_major_is l_customer_id_i
0 Windows 7 90418
1 Windows 7 90418
2 Windows 7 90418
代码:
for name, group in df.groupby('l_customer_id_i').agg(lambda x: ','.join(x)):
print name
print group
我试图循环遍历聚合数据,但出现错误:
ValueError: too many values to unpack
我希望循环遍历每个组。我该怎么做?
解决方案 1:
df.groupby('l_customer_id_i').agg(lambda x: ','.join(x))
确实已经返回了一个数据框,因此您无法再循环遍历这些组。
一般来说:
df.groupby(...)
返回一个GroupBy
对象(DataFrameGroupBy 或 SeriesGroupBy),使用它,您可以遍历组(如此处的文档中所述)。您可以执行以下操作:
grouped = df.groupby('A')
for name, group in grouped:
...
当您在 groupby 上应用函数时,在您的示例中
df.groupby(...).agg(...)
(但也可以是,,,transform
... ),您将将函数应用于不同组的结果组合在一个数据框中(groupby 的“拆分-应用-组合”范例的应用和组合步骤)。因此,此结果将始终再次是 DataFrame(或取决于所应用函数的 Series)。apply
`mean`
解决方案 2:
pd.DataFrame
以下是对按列分组的进行迭代的示例atable
。对于此示例,在循环内生成 SQL 数据库的“创建”语句for
:
import pandas as pd
def main():
df1 = pd.DataFrame({
'atable': ['Users', 'Users', 'Domains', 'Domains', 'Locks'],
'column': ['col_1', 'col_2', 'col_a', 'col_b', 'col'],
'column_type': ['varchar', 'varchar', 'int', 'varchar', 'varchar'],
'is_null': ['No', 'No', 'Yes', 'No', 'Yes'],
})
print(df1)
df1_grouped = df1.groupby('atable')
# iterate over each group
for group_name, df_group in df1_grouped:
print("
-- Group with {} rows(s)".format(len(df_group)))
print('CREATE TABLE {}('.format(group_name))
x = 0
for row_index, row in df_group.iterrows():
x = x + 1
col = row['column']
column_type = row['column_type']
is_null = 'NOT NULL' if row['is_null'] == 'No' else ''
if x < len(df_group):
print(' {} {} {},'.format(col, column_type, is_null))
else:
print(' {} {} {}'.format(col, column_type, is_null))
print(");")
if __name__ == '__main__':
main()
输出
atable column column_type is_null
0 Users col_1 varchar No
1 Users col_2 varchar No
2 Domains col_a int Yes
3 Domains col_b varchar No
4 Locks col varchar Yes
-- Group with 2 rows(s)
CREATE TABLE Domains(
col_a int ,
col_b varchar NOT NULL
);
-- Group with 1 rows(s)
CREATE TABLE Locks(
col varchar
);
-- Group with 2 rows(s)
CREATE TABLE Users(
col_1 varchar NOT NULL,
col_2 varchar NOT NULL
);
解决方案 3:
如果您的数据框已经创建,您可以迭代索引值。
df = df.groupby('l_customer_id_i').agg(lambda x: ','.join(x))
for name in df.index:
print name
print df.loc[name]
解决方案 4:
循环遍历 groupby 对象
当您对 DataFrame/Series 进行 groupby 时,您将创建一个pandas.core.groupby.generic.DataFrameGroupBy
定义该__iter__()
方法的对象,因此可以像定义此方法的任何其他对象一样对其进行迭代。它可以转换为列表/元组/迭代器等。在每次迭代中,它返回一个元组,其第一个元素是 grouper 键,第二个元素是分组创建的数据框;您可以将其视为迭代,dict_items
在每次迭代中,项目都是键值元组。除非您在 groupby 对象上选择一列或多列,否则它会返回数据框的所有列。以下代码的输出说明了这一点。
import pandas as pd
from IPython.display import display
df = pd.DataFrame({
'A': ['g1', 'g1', 'g2', 'g1'],
'B': [1, 2, 3, 4],
'C': ['a', 'b', 'c', 'd']
})
grouped = df.groupby('A')
list(grouped) # OK
dict(iter(grouped)) # OK
for x in grouped:
print(f" Type of x: {type(x).__name__}
Length of x: {len(x)}")
print(f"Value of x[0]: {x[0]}
Type of x[1]: {type(x[1]).__name__}")
display(x[1])
循环遍历 groupby 对象的一个非常有用的用例是将数据框拆分为单独的文件。例如,以下代码从单个数据框创建两个 csv 文件(g_0.csv 和 g_1.csv)。
for i, (k, g) in enumerate(df.groupby('A')):
g.to_csv(f"g_{i}.csv")
循环遍历分组数据框
如上所述,groupby 对象按键将数据框拆分为数据框。因此,您可以像任何其他数据框一样循环遍历每个分组数据框。请参阅此答案以了解遍历数据框的全面方法。性能最高的方法可能是itertuples()
。以下是使用分组数据框上的循环创建嵌套字典的示例:
out = {}
for k, g in grouped: # loop over groupby
out[k] = {}
for row in g.itertuples(): # loop over dataframe
out[k][row.B] = row.C
print(out)
# {'g1': {1: 'a', 2: 'b', 4: 'd'}, 'g2': {3: 'c'}}
扫码咨询,免费领取项目管理大礼包!