【问题标题】:Python Pandas : Convert multiple rows into single row, ignoring NaN'sPython Pandas:将多行转换为单行,忽略 NaN
【发布时间】:2016-10-17 23:02:59
【问题描述】:

我有一个类似于下面提到的DataFrame

 Age    Sex    Name ....
 12     NaN    NaN
 NaN    Male   NaN
 NaN    NaN    David

我想将其转换为一行的数据框,忽略 NaN 并合并它们

 Age    Sex    Name
 12     Male   David

Pandas 是怎么做到的?

【问题讨论】:

    标签: python python-2.7 pandas dataframe


    【解决方案1】:

    您可以使用pd.concat.dropna().reset_index() 之后的所有columns 组合起来,如下所示:

    pd.concat([df[col].dropna().reset_index(drop=True) for col in df], axis=1)
    

    得到:

        Age   Sex   Name
    0  12.0  Male  David
    

    【讨论】:

    • 尝试此操作时出现属性错误.. AttributeError: 'DataFrame' object has no attribute 'items'
    【解决方案2】:

    另一种方法是 apply 调用 first_valid_index 以返回第一个有效行值的 lambda:

    In [246]:
    df.apply(lambda x: pd.Series(x[x.first_valid_index()]))
    
    Out[246]:
        Age   Sex   Name
    0  12.0  Male  David
    

    【讨论】:

      【解决方案3】:

      这太恶心了。熊猫不会自动重塑索引;/。所以你必须做一些操作。不知道哪个最好:

      import numpy as np,pandas as pd
      
      df= '''
       12     NaN    NaN
       NaN    Male   NaN
       NaN    NaN    David'''
      
      df = np.array(df.split())
      
      df.shape=(3,3)
      
      df = pd.DataFrame(df,columns='Age   Sex   Name'.split())
      df.replace('NaN',np.nan,True)
      
      def func(x):
          x.dropna(inplace=True)
          x.reset_index(inplace=True,drop=True)
          #s=pd.Series(vals,index=range(vals.shape[0]))
          #print vals.shape
          #print x.shape
          return x
      
      def func1(x):
          x=x.dropna().values
          idx=range(x.shape[0])
          x=pd.Series(x,index=idx)
          #print vals.shape
          #print x.shape
          return x
      
      def func2(x):
          idx=x.first_valid_index()
          x=x[idx]
          x=pd.Series(x)
          return x
      
      print '#'*20
      print df
      print '#'*20
      print 1,df.apply(func,axis=0)
      print '#'*20
      print 2,df.apply(func1,axis=0)
      print '#'*20
      print 3,df.apply(func2,axis=0)
      print '#'*20
      print 3,pd.DataFrame({colId: df[colId].dropna().values for colId in df})
      
      '''
      output:
      
      ####################
         Age   Sex   Name
      0   12   NaN    NaN
      1  NaN  Male    NaN
      2  NaN   NaN  David
      ####################
      1   Age   Sex   Name
      0  12  Male  David
      ####################
      2   Age   Sex   Name
      0  12  Male  David
      ####################
      3   Age   Name   Sex
      0  12  David  Male
      
      '''
      

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 2018-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2018-01-07
        • 1970-01-01
        • 2018-06-26
        相关资源
        最近更新 更多