通过切换列名来移动熊猫系列值?

时间:2019-01-15 00:57:31

标签: python pandas

我有一个DF,但是某些系列的最后一个值应该放在另一个中。发生这种情况的原因是列名尚未标准化-即,有些是“ Wx_y_x_PRED”,有些是“ Wx_x_y_PRED”。我在编写一个函数时会遇到困难,该函数将简单地查找> = 225 NaN的列并更改分配给它的列。

我编写了一个函数,由于某种原因它有时会起作用,有时会不起作用。当它这样做时,它会在其后进一步创建约850列(OG数据帧约为420,其中包含重复的列)。我希望有一些可以重新分配价值的东西。如果它自动删除不正确的列,那也很棒,但是当我的函数最初工作时,我只是使用了.dropna(thresh = 2)。

这是原来的样子:

in: df = pd.DataFrame(data = {'W10_IND_JAC_PRED': ['NaN','NaN','NaN','NaN','NaN',2],
                      'W10_JAC_IND_PRED': [1,2,1,2,1,'NAN']})
out:df
W10_IND_JAC_PRED    W10_JAC_IND_PRED
0   NaN                   1
1   NaN                   2
2   NaN                   1
3   NaN                   2
4   NaN                   1
W   2                   NAN

我写了这个,偶尔能用,但是大多数时候不行,我不确定为什么。

def switch_cols(x):
    """Takes mismatched columns (where only the last value != NaN) and changes order of team column names"""
    if x.isna().sum() == 5:
        col_string = x.name.split('_')
        col_to_switch = ('_').join([col_string[0],col_string[2],col_string[1],'PRED'])
        df[col_to_switch]['row_name'] = x[-1]
    else:
        pass    
    return x

在大多数情况下,它只是返回给我完全相同的DF,但这是理想的结果。

W10_IND_JAC_PRED    W10_JAC_IND_PRED
0   NaN                   1
1   NaN                   2
2   NaN                   1
3   NaN                   2
4   NaN                   1
W   2                     2

任何人都有任何提示,或者可以分享为什么我的功能可能在10%的时间内起作用?

编辑:

所以这是我写的有效的“ for”循环。我知道在保留原始列名的同时,必须有一种更加Python化的方式来做到这一点。

for i in range(df.shape[1]): if df.iloc[:,i].isna().sum() == 5: split_nan_col = df.columns[i].split('_') correct_col_name = ('_').join([split_nan_col[0],split_nan_col[2],split_nan_col[1],split_nan_col[3]]) df.loc[5,correct_col_name] = df.loc[5,df.columns[i]] else: pass

1 个答案:

答案 0 :(得分:1)

split之前使用frozenset(将返回订单列表),然后我们进行join:请注意,此解决方案可以实现到更多列

df.columns=df.columns.str.split('_').map(frozenset).map('_'.join)
df.mask(df=='NaN').groupby(level=0,axis=1).first() # groupby first will return the first not null value 
   PRED_JAC_W10_IND
0                 1
1                 2
2                 1
3                 2
4                 1
5                 2