Python 使用Pandas组合数据帧中两行的不同部分

Python 使用Pandas组合数据帧中两行的不同部分,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个大的(>10000行)数据帧,如下所示,我必须通过组a的列1、列2、列3和组b或组c的列4、列5组合同名行(b和c不会同时存在) 我可以在网上找到如何组合(加起来)每一行的列,而不是放在不同的部分 原始数据帧 名称 组 上校1 col_2 第3栏 第4栏 第5栏 安 A. 1. 楠 2. 3. 楠 安 B 1. 楠 楠 2. 3. 本 A. 0 1. 2. 1. 楠 本 C 0 楠 楠 3. 楠 猫 A. 2. 3. 楠 楠 楠 有点特别,但有一种方法可以做到这一点,即按名称和组对数据帧

我有一个大的(>10000行)数据帧,如下所示,我必须通过组a列1、列2、列3组b组c列4、列5组合同名行(bc不会同时存在)

我可以在网上找到如何组合(加起来)每一行的列,而不是放在不同的部分

原始数据帧

名称 组 上校1 col_2 第3栏 第4栏 第5栏 安 A. 1. 楠 2. 3. 楠 安 B 1. 楠 楠 2. 3. 本 A. 0 1. 2. 1. 楠 本 C 0 楠 楠 3. 楠 猫 A. 2. 3. 楠 楠 楠
有点特别,但有一种方法可以做到这一点,即按名称和组对数据帧进行排序,然后将
df
分为两部分(即A组的col1/2/3),执行
groupby
并在第一个
df
上使用
first()
,在第二个
last()
,然后使用
concat
重新组合:

import pandas as pd

df.sort_values(['name','group'],ascending=True,inplace=True)

one = df.iloc[:,:5]
two = pd.concat([df.iloc[:,:2],df[['col_4','col_5']]],axis=1)

def my_func(df1,df2,col):
    return pd.concat([df1.groupby(col).first(),
                      df2.groupby(col).last()],
                      axis=1).drop('group',axis=1)
 
res = my_func(one,two,'name')
其中打印:

print(res)
      col_1  col_2  col_3  col_4  col_5
name                                   
ann       1    NaN   2.00   2.00   3.00
ben       0   1.00   2.00   3.00    NaN
cat       2   3.00    NaN    NaN    NaN

如果我没弄错的话,这可以满足您的需要。

IIUC,您需要分配分类值,然后在分组之前进行排序:

out = (df.assign(k=pd.Categorical(df['group'],['b','c','a'],ordered=True))
         .sort_values(['name','k'])
          .groupby("name",sort=False).first()).drop(["group","k"],1).reset_index()


下面是另一种方法:

第一步是对
name
group
中的值进行排序,以确保它们的顺序正确,然后将它们设置为索引。然后我们根据列末尾的数字制作一个字典。然后我们在
groupby()
中使用
.agg
,并传入新词典

g = ['name','group']
df = df.sort_values(by = g,ascending = (1,1)).set_index(g)
d = {i : 'first' if int(i[-1])<=3 else 'last' for i in df.columns}
new_df = df.groupby(level=0).agg(d)
g=['name','group']
df=df.sort_值(by=g,升序=(1,1)).set_索引(g)

d={i:'first'if int(i[-1])我想我不会使用这种方法,因为对于我的数据,我不确定所有的b/c组都与a组相同,或者在列1-2-3中都是NaN,谢谢!创建单独的组,然后将它们连接到一个结果数据帧中。确保连接的键是唯一的。
g = ['name','group']
df = df.sort_values(by = g,ascending = (1,1)).set_index(g)
d = {i : 'first' if int(i[-1])<=3 else 'last' for i in df.columns}
new_df = df.groupby(level=0).agg(d)