将数据框按行分组保存到恰好两行
saving dataframe groupby rows to exactly two lines
我有一个数据框,我想根据特定列对行进行分组。每组中的行数至少为 4,最多为 50。我想将组中的一列保存为两行。如果 groupsize 是偶数,假设 2n
,那么一行中有 n
行,第二行中剩余的 n
行。如果是奇数,n+1
和 n
或 n
和 n+1
都可以。
例如,
import pandas as pd
from io import StringIO
data = """
id,name
1,A
1,B
1,C
1,D
2,E
2,F
2,ds
2,G
2, dsds
"""
df = pd.read_csv(StringIO(data))
我要分组id
df.groupby('id',sort=False)
然后得到一个像
这样的数据框
id name
0 1 A B
1 1 C D
2 2 E F ds
3 2 G dsds
这种方法有点复杂,但确实有效;
def func(s: pd.Series):
mid = max(s.shape[0]//2 ,1)
l1 = ' '.join(list(s[:mid]))
l2 = ' '.join(list(s[mid:]))
return [l1, l2]
df_new = df.groupby('id').agg(func)
df_new["name1"]= df_new["name"].apply(lambda x: x[0])
df_new["name2"]= df_new["name"].apply(lambda x: x[1])
df = df_new.drop(labels="name", axis=1).stack().reset_index().drop(labels = ["level_1"], axis=1).rename(columns={0:"name"}).set_index("id")
可能不是最有效的解决方案,但它有效:
import numpy as np
df = df.sort_values('id')
# next 3 lines: for each group find the separation
df['range_idx'] = range(0, df.shape[0])
df['mean_rank_group'] = df.groupby(['id'])['range_idx'].transform(np.mean)
df['separate_column'] = df['range_idx'] < df['mean_rank_group']
# groupby itself with the help of additional column
df.groupby(['id', 'separate_column'], as_index=False)['name'].agg(','.join).drop(
columns='separate_column')
我有一个数据框,我想根据特定列对行进行分组。每组中的行数至少为 4,最多为 50。我想将组中的一列保存为两行。如果 groupsize 是偶数,假设 2n
,那么一行中有 n
行,第二行中剩余的 n
行。如果是奇数,n+1
和 n
或 n
和 n+1
都可以。
例如,
import pandas as pd
from io import StringIO
data = """
id,name
1,A
1,B
1,C
1,D
2,E
2,F
2,ds
2,G
2, dsds
"""
df = pd.read_csv(StringIO(data))
我要分组id
df.groupby('id',sort=False)
然后得到一个像
这样的数据框 id name
0 1 A B
1 1 C D
2 2 E F ds
3 2 G dsds
这种方法有点复杂,但确实有效;
def func(s: pd.Series):
mid = max(s.shape[0]//2 ,1)
l1 = ' '.join(list(s[:mid]))
l2 = ' '.join(list(s[mid:]))
return [l1, l2]
df_new = df.groupby('id').agg(func)
df_new["name1"]= df_new["name"].apply(lambda x: x[0])
df_new["name2"]= df_new["name"].apply(lambda x: x[1])
df = df_new.drop(labels="name", axis=1).stack().reset_index().drop(labels = ["level_1"], axis=1).rename(columns={0:"name"}).set_index("id")
可能不是最有效的解决方案,但它有效:
import numpy as np
df = df.sort_values('id')
# next 3 lines: for each group find the separation
df['range_idx'] = range(0, df.shape[0])
df['mean_rank_group'] = df.groupby(['id'])['range_idx'].transform(np.mean)
df['separate_column'] = df['range_idx'] < df['mean_rank_group']
# groupby itself with the help of additional column
df.groupby(['id', 'separate_column'], as_index=False)['name'].agg(','.join).drop(
columns='separate_column')