对于DataFrame的每一行,在给定条件的情况下获取第一列的索引到新列中

时间:2019-12-02 16:41:44

标签: python pandas

这是我的数据框的一部分。

data = [
    ['1245', np.nan, np.nan, 1.0, 1.0, ''],
    ['1246', np.nan, 1.0, 1.0, 1.0, ''],
    ['1247', 1.0, 1.0, 1.0, 1.0, ''],
    ['1248', 1.0, 1.0, np.nan, np.nan, ''],
    ['1249', np.nan, 1.0, np.nan, 1.0, '']
]

df = pd.DataFrame(data, columns = ['city_code', 'apr_12', 'may_12', 'jul_12', 'aug_12', 'first_index'])

df

我想用第一个“ 1.0”(浮点数)的列的索引(apr_12,may_12,jun_12和aug_12)填充“ first_index”列。 例如,我想在第一行“ 2”的“ first_index”列中看到,因为这是该行的第一个“ 1.0”所在的位置。那样就可以了,而不必考虑“ city_code”列。

仅供参考:起初,NaN值是“ 0.0”(浮点数),但是我认为继续使用NaN值和诸如first_valid_index()之类的函数会更容易(但我无法使其正常工作。 )。如果需要的话,我不会放零。

你们对如何解决这个问题有任何想法吗?非常感谢

3 个答案:

答案 0 :(得分:4)

鉴于您只有NaN和1.0,可以这样做:

df['first_index'] = df[['apr_12', 'may_12', 'jul_12', 'aug_12']].fillna(0).to_numpy().argmax(1)

结果:

  city_code  apr_12  may_12  jul_12  aug_12  first_index
0      1245     NaN     NaN     1.0     1.0            2
1      1246     NaN     1.0     1.0     1.0            1
2      1247     1.0     1.0     1.0     1.0            0
3      1248     1.0     1.0     NaN     NaN            0
4      1249     NaN     1.0     NaN     1.0            1

(如果您说的是原始版本中的零而不是NaN,那么您当然可以跳过fillna(0)

或更短(对于具有NaN的df):

df['first_index'] = np.nanargmin(df[['apr_12', 'may_12', 'jul_12', 'aug_12']], 1)

答案 1 :(得分:1)

您可以使用每一行并使用np.where查找第一个非空值索引

col_list = ['apr_12', 'may_12', 'jul_12', 'aug_12']
df['first_index'] = df[col_list].apply(lambda x: (np.where(~x.isnull())[0][0]), axis=1)
print(df)

输出:

  city_code  apr_12  may_12  jul_12  aug_12  first_index
0      1245     NaN     NaN     1.0     1.0            2
1      1246     NaN     1.0     1.0     1.0            1
2      1247     1.0     1.0     1.0     1.0            0
3      1248     1.0     1.0     NaN     NaN            0
4      1249     NaN     1.0     NaN     1.0            1

按照Stef的建议使用argmax或argmax将返回最大值和最小值的索引(nanargmin / nanargmax忽略nan),因此,如果您的df值不全为1,则它将无法给出第一个非nan索引

答案 2 :(得分:1)

使用idxmaxget_indexer

data = [
    ['1245', np.nan, np.nan, 1.0, 1.0, ''],
    ['1246', np.nan, 1.0, 1.0, 1.0, ''],
    ['1247', 1.0, 1.0, 1.0, 1.0, ''],
    ['1248', 1.0, 1.0, np.nan, np.nan, ''],
    ['1249', np.nan, 1.0, np.nan, 1.0, '']
]

df = pd.DataFrame(data, columns = ['city_code', 'apr_12', 
                                   'may_12', 'jul_12', 'aug_12', 'first_index'])

df_out = df.set_index('city_code')
df_out['first_index'] = df_out.iloc[:,:-1].idxmax(axis=1)

df_out['position_first_index'] = df_out.columns.get_indexer(df_out['first_index'])

df_out.reset_index()

输出:

  city_code  apr_12  may_12  jul_12  aug_12 first_index  position_first_index
0      1245     NaN     NaN     1.0     1.0      jul_12                     2
1      1246     NaN     1.0     1.0     1.0      may_12                     1
2      1247     1.0     1.0     1.0     1.0      apr_12                     0
3      1248     1.0     1.0     NaN     NaN      apr_12                     0
4      1249     NaN     1.0     NaN     1.0      may_12                     1