【问题标题】:evaluate every cell and return column head if not null pandas df如果不是 null pandas df,则评估每个单元格并返回列头
【发布时间】:2018-03-11 04:59:50
【问题描述】:

我有 pandas.df 233 行 * 234 列,如果不是 nan,我需要评估每个单元格并返回相应的列标题,到目前为止,我写了以下内容:

#First get a list of all column names (except column 0):

col_list=[]

for column in df.columns[1:]:
    col_list.append(column)

#Then I try to iterate through every cell and evaluate for Null
#Also a counter is initiated to take the next col_name from col_list
#when count reach 233

for index, row in df.iterrows():
    count = 0
    for x in row[1:]:
        count = count+1
        for col_name in col_list:
            if count >= 233: break
            elif str(x) != 'nan':
                print col_name 

代码并没有完全做到这一点,我需要更改什么才能让代码在 233 行后中断并转到下一个 col_name?

Example:

    Col_1   Col_2    Col_3
1    nan     13       nan
2    10      nan      nan
3    nan      2        5
4    nan     nan       4

output:      
1   Col_2
2   Col_1
3   Col_2
4   Col_3
5   Col_3

【问题讨论】:

    标签: python pandas iterator nested-loops


    【解决方案1】:

    如果第一列是index stack,我认为您需要 - 它删除所有NaNs,然后通过reset_indexMultiindex 的第二级获取值并选择或通过Series 构造函数与@ 987654323@:

    s = df.stack().reset_index()['level_1'].rename('a')
    print (s)
    0    Col_2
    1    Col_1
    2    Col_2
    3    Col_3
    4    Col_3
    Name: a, dtype: object
    

    或者:

    s = pd.Series(df.stack().index.get_level_values(1))
    print (s)
    0    Col_2
    1    Col_1
    2    Col_2
    3    Col_3
    4    Col_3
    dtype: object
    

    如果需要输出为list:

    L = df.stack().index.get_level_values(1).tolist()
    print (L)
    ['Col_2', 'Col_1', 'Col_2', 'Col_3', 'Col_3']
    

    详情

    print (df.stack())
    1  Col_2    13.0
    2  Col_1    10.0
    3  Col_2     2.0
       Col_3     5.0
    4  Col_3     4.0
    dtype: float64
    

    【讨论】:

      【解决方案2】:

      我会使用 jezrael 的堆栈解决方案。

      但是,如果您对Numpy 方式感兴趣,这通常会更快。

      In [4889]: np.tile(df.columns, df.shape[0])[~np.isnan(df.values.ravel())]
      Out[4889]: array(['Col_2', 'Col_1', 'Col_2', 'Col_3', 'Col_3'], dtype=object)
      

      时间

      In [4913]: df.shape
      Out[4913]: (100, 3)
      
      In [4914]: %timeit np.tile(df.columns, df.shape[0])[~np.isnan(df.values.ravel())]
      10000 loops, best of 3: 35.8 µs per loop
      
      In [4915]: %timeit df.stack().index.get_level_values(1)
      1000 loops, best of 3: 335 µs per loop
      
      In [4905]: df.shape
      Out[4905]: (100000, 3)
      
      In [4907]: %timeit np.tile(df.columns, df.shape[0])[~np.isnan(df.values.ravel())]
      100 loops, best of 3: 5.98 ms per loop
      
      In [4908]: %timeit df.stack().index.get_level_values(1)
      100 loops, best of 3: 11.7 ms per loop
      

      根据您的需要(可读性、速度、可维护性等)选择

      【讨论】:

      • 太棒了。瓷砖很神奇:)。想不出更快的方法
      【解决方案3】:

      你可以使用dropna

      df.dropna(axis=1).columns
      

      轴:{0 或“索引”,1 或“列”}

      如何:{‘任何’,‘所有’}

      基本上你用dropna去掉null,axis = 1是去掉列,how="any"去掉是列中至少有一个为null,.columns得到剩下的header。

      【讨论】:

      • 不确定这是如何应用的,如果找到 nan,.dropna 将删除列,但这不是所需的输出。
      • 我需要的是评估每行的每个单元格并仅在单元格时返回列名!= nan
      • @haytham 剩下的列不会是 cell != nan 的列?
      • @haytham 也是 'nan' 而不是 NaN,你可以使用 df.replace("nan", numpy.nan)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 2016-05-17
      相关资源
      最近更新 更多