如何将python中的列值转置为多行?
How to transpose a column into multiple rows for a column value in python?
如果我有一个数据框并且它有 col1 是文件名,col2 是我想用它的值转置到文件名中的值,例如:
Input:
col1 col2
file1 text_0
file1 text_1
file1 text_2
file2 text_0
file2 text_1
file2 text_2
file2 text_3
file3 text_0
Output:
col1 col2 col3 col4 col5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
您似乎有 DataFrames,这意味着您正在使用 Pandas。
考虑检查 pandas.transpose or pandas.pivot,具体取决于您需要什么。
试试这个:
new_df = df.pivot(columns='col1').droplevel(0,axis=1).rename_axis(columns='col1').apply(lambda x: pd.Series(x.dropna().values)).fillna('')
new_df.index = new_df.reset_index(drop=True).index+2
new_df = new_df.T.add_prefix('col_')
输出:
col_2 col_3 col_4 col_5
col1
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
或您的新方式:
new_df = df.pivot(columns='col1').droplevel(0,axis=1).apply(lambda x: pd.Series(x.dropna().values)).fillna('')
new_df.index = new_df.index+2
new_df = new_df.T.add_prefix('col_')
new_df = new_df.rename_axis(columns='col1', index=None)
输出:
col1 col_2 col_3 col_4 col_5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
由于 OP 不需要主元,这里有一个无主元的解决方案:
df = df.groupby('col1')['col2'].agg(list).apply(pd.Series).fillna('')
df.columns = list(range(2,6))
df = df.add_prefix('col_')
df = df.rename_axis(columns='col1', index=None)
输出:
col1 col_2 col_3 col_4 col_5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
第一个想法是使用 GroupBy.cumcount
for counter of duplicated values of col1
for new columns names and reshape by Series.unstack
:
df = (df.set_index(['col1',df.groupby('col1').cumcount()])['col2']
.unstack(fill_value='')
.reset_index())
df.columns = [f'col{x}' for x in range(1, len(df.columns) + 1)]
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
或创建 Series
列表并避免使用 apply(pd.Series)
、,最好使用 DataFrame 构造函数:
s = df.groupby('col1')['col2'].apply(list)
df = pd.DataFrame(s.tolist(), index=s.index).reset_index().fillna('')
df.columns = [f'col{x}' for x in range(1, len(df.columns) + 1)]
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
选择:
s = df.groupby('col1')['col2'].apply(list)
L = [[k] + v for k, v in s.items()]
df = pd.DataFrame(L).fillna('').rename(columns=lambda x: f'col{x+1}')
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
这应该可以解决问题:
df2=df.groupby("col1").agg(lambda x: (dict((f"col{id+2}",val) for id,val in enumerate(list(x)))))
df2=df2["col2"].apply(pd.Series).reset_index()
输出:
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2 NaN
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0 NaN NaN NaN
如果我有一个数据框并且它有 col1 是文件名,col2 是我想用它的值转置到文件名中的值,例如:
Input:
col1 col2
file1 text_0
file1 text_1
file1 text_2
file2 text_0
file2 text_1
file2 text_2
file2 text_3
file3 text_0
Output:
col1 col2 col3 col4 col5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
您似乎有 DataFrames,这意味着您正在使用 Pandas。 考虑检查 pandas.transpose or pandas.pivot,具体取决于您需要什么。
试试这个:
new_df = df.pivot(columns='col1').droplevel(0,axis=1).rename_axis(columns='col1').apply(lambda x: pd.Series(x.dropna().values)).fillna('')
new_df.index = new_df.reset_index(drop=True).index+2
new_df = new_df.T.add_prefix('col_')
输出:
col_2 col_3 col_4 col_5
col1
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
或您的新方式:
new_df = df.pivot(columns='col1').droplevel(0,axis=1).apply(lambda x: pd.Series(x.dropna().values)).fillna('')
new_df.index = new_df.index+2
new_df = new_df.T.add_prefix('col_')
new_df = new_df.rename_axis(columns='col1', index=None)
输出:
col1 col_2 col_3 col_4 col_5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
由于 OP 不需要主元,这里有一个无主元的解决方案:
df = df.groupby('col1')['col2'].agg(list).apply(pd.Series).fillna('')
df.columns = list(range(2,6))
df = df.add_prefix('col_')
df = df.rename_axis(columns='col1', index=None)
输出:
col1 col_2 col_3 col_4 col_5
file1 text_0 text_1 text_2
file2 text_0 text_1 text_2 text_3
file3 text_0
第一个想法是使用 GroupBy.cumcount
for counter of duplicated values of col1
for new columns names and reshape by Series.unstack
:
df = (df.set_index(['col1',df.groupby('col1').cumcount()])['col2']
.unstack(fill_value='')
.reset_index())
df.columns = [f'col{x}' for x in range(1, len(df.columns) + 1)]
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
或创建 Series
列表并避免使用 apply(pd.Series)
、
s = df.groupby('col1')['col2'].apply(list)
df = pd.DataFrame(s.tolist(), index=s.index).reset_index().fillna('')
df.columns = [f'col{x}' for x in range(1, len(df.columns) + 1)]
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
选择:
s = df.groupby('col1')['col2'].apply(list)
L = [[k] + v for k, v in s.items()]
df = pd.DataFrame(L).fillna('').rename(columns=lambda x: f'col{x+1}')
print (df)
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0
这应该可以解决问题:
df2=df.groupby("col1").agg(lambda x: (dict((f"col{id+2}",val) for id,val in enumerate(list(x)))))
df2=df2["col2"].apply(pd.Series).reset_index()
输出:
col1 col2 col3 col4 col5
0 file1 text_0 text_1 text_2 NaN
1 file2 text_0 text_1 text_2 text_3
2 file3 text_0 NaN NaN NaN