[英]split pandas dataframe based on string column value
我正在努力尝试将我的数据帧拆分为 3 个新的数据帧,其中在供应商名称更改时发生拆分。 我已经搜索了现有的问题。 如何根据列行和Pandas & python 拆分数据帧:根据包含子字符串的列值将数据帧拆分为许多数据帧接近但我无法获得我想要的输出。
这里附上一个玩具数据集来说明我的问题:
df = pd.DataFrame({'Supplier': ['Supplier1', 'Supplier1', 'Supplier2', 'Supplier2', 'Supplier2', 'Supplier3','Supplier3'], 'Class' : ['A', 'A','A','A','A','B','B']})
我试过(不成功)
df1 = df.iloc[:df.index[df['Supplier'] == 'Supplier1'].tolist()[0]]
df2 = df.iloc[df.index[df['Supplier'] == 'Supplier2'].tolist()[0]+1:]
df3 = df.iloc[df.index[df['Supplier'] == 'Supplier3'].tolist()[0]+1:]
我想要达到的结果是:
Supplier Class
0 Supplier1 A
1 Supplier1 A
Supplier Class
0 Supplier2 A
1 Supplier2 A
2 Supplier2 A
Supplier Class
0 Supplier3 B
1 Supplier3 B
对此的任何帮助将不胜感激。 谢谢!
更新:使用:
df1 = {i:group for i,group in df.groupby( df['Supplier'].ne(df['Supplier'].shift()).cumsum() )}
给出:
{1: Supplier Class
0 Supplier1 A
1 Supplier1 A, 2: Supplier Class
2 Supplier2 A
3 Supplier2 A
4 Supplier2 A, 3: Supplier Class
5 Supplier3 B
6 Supplier3 B}
我需要拆分成单独的数据帧,所以我做了:
df3 = pd.DataFrame.from_dict({i:group for i,group in df1.groupby(df1['Supplier'].ne(df1['Supplier'].shift()).cumsum() )},orient='index', columns= ['Class'])
但它给出了错误
df3 = pd.DataFrame.from_dict({i:group for i,group in df1.groupby(df1['Supplier'].ne(df1['Supplier'].shift()).cumsum() )},orient='index', columns= ['Class'])
AttributeError: 'dict' object has no attribute 'groupby'
为唯一的供应商值创建数据框:
dict(zip(df.groupby('Supplier')))
每次supplier
列中的值更改时创建数据框:
dfs = {i:group.reset_index(drop=True)
for i,group in df.groupby( df['Supplier'].ne(df['Supplier'].shift()).cumsum() )}
更新
获得三个单独的数据帧与最终想要使用pd.DataFrame(..)
不兼容,这显然会创建一个唯一的数据帧,因此我的解决方案是创建一个数据帧字典,其中每个字典都被访问为整数值 1 到n. 我们可以为每个人重置索引,只需执行以下操作:
{i:group.reset_index(drop=True) for i,group in df.groupby( df['supplier'].ne(df['supplier'].shift()).cumsum() )}
我们可以使用pd.concat
如@anky_91 建议的那样,在每次提供者列中的值发生变化时,获得一个索引恢复的单个数据框
dfs_concat = pd.concat([group.reset_index(drop=True)
for _,group in df.groupby( df['Supplier'].ne(df['Supplier'].shift())
.cumsum() )])
print(dfs_concat)
Supplier Class
0 Supplier1 A
1 Supplier1 A
0 Supplier2 A
1 Supplier2 A
2 Supplier2 A
0 Supplier3 B
1 Supplier3 B
但如果后者是寻求的解决方案,我们可以简单地使用groupby.cumcount
df.index = df.groupby(df['Supplier'].ne(df['Supplier'].shift()).cumsum()).cumcount()
print(df)
Supplier Class
0 Supplier1 A
1 Supplier1 A
0 Supplier2 A
1 Supplier2 A
2 Supplier2 A
0 Supplier3 B
1 Supplier3 B
尝试这个,
df = pd.DataFrame({'Supplier': ['Supplier1', 'Supplier1', 'Supplier2', 'Supplier2', 'Supplier2', 'Supplier3','Supplier3'], 'Class' : ['A', 'A','A','A','A','B','B']})
df1 = df[df.Supplier=='Supplier1']
df2 = df[df.Supplier=='Supplier2']
df3 = df[df.Supplier=='Supplier3']
或者你可以这样做,
new_df=df.pivot(columns='Supplier')
如果您有“供应商”,则可以获得许多列。
输出:
Supplier Supplier1 Supplier2 Supplier3
0 A NaN NaN
1 A NaN NaN
2 NaN A NaN
3 NaN A NaN
4 NaN A NaN
5 NaN NaN B
6 NaN NaN B
我相信这可以实现您想要的拆分:
groups = [group.reset_index()[['Supplier', 'Class']] for _, group in df.groupby('Supplier')]
你可以得到你的例子的确切输出
for group in groups:
print(group)
输出:
Supplier Class
0 Supplier1 A
1 Supplier1 A
Supplier Class
0 Supplier2 A
1 Supplier2 A
2 Supplier2 A
Supplier Class
0 Supplier3 B
1 Supplier3 B
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.