Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将同一类别的多行合并为一行?_Python_Pandas_Dataframe_Merge - Fatal编程技术网

Python 如何将同一类别的多行合并为一行?

Python 如何将同一类别的多行合并为一行?,python,pandas,dataframe,merge,Python,Pandas,Dataframe,Merge,我试图从图中得到表1到表2,但我似乎无法正确地得到它。我尝试将透视表的列A-D从行更改为列。然后我尝试groupby,但它没有给我一行,而是弄乱了我的数据帧 您可以使用列中的值填充空值并删除重复项: 与: df = pd.DataFrame([["A", pd.np.nan, pd.np.nan, "Y", "Z"], [pd.np.nan, "B", pd.np.nan, "Y", "Z"], [pd.np.nan,pd.np.nan,

我试图从图中得到表1到表2,但我似乎无法正确地得到它。我尝试将透视表的列A-D从行更改为列。然后我尝试groupby,但它没有给我一行,而是弄乱了我的数据帧


您可以使用列中的值填充空值并删除重复项:

与:

df = pd.DataFrame([["A", pd.np.nan, pd.np.nan, "Y", "Z"],
              [pd.np.nan, "B", pd.np.nan, "Y", "Z"],
              [pd.np.nan,pd.np.nan, "C", "Y", "Z"]], columns=list("ABCDE"))
df
     A    B    C  D  E
0    A  NaN  NaN  Y  Z
1  NaN    B  NaN  Y  Z
2  NaN  NaN    C  Y  Z

df.ffill().bfill().drop_duplicates()
   A  B  C  D  E
0  A  B  C  Y  Z
df.ffill().bfill()
给出:

   A  B  C  D  E
0  A  B  C  Y  Z
1  A  B  C  Y  Z
2  A  B  C  Y  Z
根据您的注释,您可以定义一个函数,用同一列中其他地方的唯一值填充第一行缺少的值

def fillna_uniq(df, col):
    if isinstance(col, list):
        for c in col:
            df.loc[df.index[0], c] = df[c].dropna().iloc[0]
    else:
        df.loc[df.index[0], col] = df[col].dropna().iloc[0]
    return df.iloc[[0]]
然后你可以做:

fillna_uniq(df.copy(), ["B", "C", "D"])
       A  B   C     D       E     F
0  Hello  I  am  lost  Pandas  Data
我想它快一点。您可以通过直接传递数据帧而不是副本来修改df


HTH

一种方法是使用
apply
dropna

假设上表中的空格实际上为空:

df = pd.DataFrame({'A':['Hello',np.nan,np.nan,np.nan],'B':[np.nan,'I',np.nan,np.nan],
                   'C':[np.nan,np.nan,'am',np.nan],
                  'D':[np.nan,np.nan,np.nan,'lost'],
                  'E':['Pandas']*4,
                  'F':['Data']*4})

print(df)
       A    B    C     D       E     F
0  Hello  NaN  NaN   NaN  Pandas  Data
1    NaN    I  NaN   NaN  Pandas  Data
2    NaN  NaN   am   NaN  Pandas  Data
3    NaN  NaN  NaN  lost  Pandas  Data
使用
apply
,您可以将lambda函数应用于数据帧的每一列,首先删除空值,然后查找最大值:

df.apply(lambda x: x.dropna().max()).to_frame().T

       A  B   C     D       E     F
0  Hello  I  am  lost  Pandas  Data
或者,如果空格实际上是空字符串,则可以执行以下操作:

df1 = df.replace(np.nan,'')
df1
       A  B   C     D       E     F
0  Hello               Pandas  Data
1         I            Pandas  Data
2            am        Pandas  Data
3                lost  Pandas  Data

df1.apply(lambda x: x[x!=''].max()).to_frame().T

       A  B   C     D       E     F
0  Hello  I  am  lost  Pandas  Data

df=df.groupby(level=0,axis=1).max()
此外,请将您的图片转换为可复制的数据示例,用于为您提供可验证的答案。它不起作用。我仍然有4行而不是1行。请阅读我的第二条评论。但是有没有办法优化这一点?我用了大约15秒的时间来进行填充。@user8706644您只能填充第一行,而不是删除副本,只保留第一行。如果你有一个巨大的df,可能会更好。我实际上运行的是df.groupby(['E,F']).ffill().bfill().drop_duplicates()自定义方法对组有效吗?当然,groupby对象只是应用了一些东西的更小的df。我稍微修改了一下这个函数,它就可以工作了:
df.groupby([“E”,“F”]).apply(lambda x:fillna_uniq(x.copy(),[“a”,“B”,“C”,“D”])).reset_index(drop=True)