熊猫:根据条件展平专栏?

时间:2017-05-09 12:46:25

标签: python pandas

我正在尝试压扁行并保留我想要的行的信息。

我有什么:

id  var1  var2 var3
1      Y     N    Y
1      N          Y
2      Y          N
2      N     Y    N
2      Y     N    Y

我想要的是什么:

id  var1  var2 var3
1      Y     N    Y
2      Y     Y    Y

基本上,它会检查是否有Y / N并始终优先考虑Y. 还有比var1,var2,var3更多的列;所以我想要更通用的东西,所以我也可以申请其他专栏。

3 个答案:

答案 0 :(得分:6)

让我们试试,您可以使用groupbysum来表现为OR,因此"优先考虑Y":

df1 = df.replace({'Y':True,'N':False})

df_out = (df1.groupby('id').sum(skipna=False)
         .astype(bool)
         .replace({True:'Y',False:'N'})
         .reset_index())

print(df_out)

输出:

   id var1 var2 var3
0   1    Y    N    Y
1   2    Y    Y    Y

答案 1 :(得分:3)

您可以使用replace + groupby + GroupBy.max + replace + reset_index

df1 = df.replace({'Y':1,'N':0, np.nan:-1})
        .groupby('id')
        .max()
        .replace({1:'Y', 0:'N',-1:np.nan})
        .reset_index()
print (df1)

   id var1 var2 var3
0   1    Y    N    Y
1   2    Y    Y    Y

编辑:

df = pd.DataFrame({
'id': [1, 1, 2, 2, 3, 3], 
'var2': ['N', 'N', 'N', 'Y', 'N', np.nan], 
'var1': ['Y', 'Y', 'Y', 'N', 'Y', np.nan], 
'var3': [np.nan, np.nan, np.nan, 'N', np.nan, 'Y']
})

print (df)
   id var1 var2 var3
0   1    Y    N  NaN
1   1    Y    N  NaN
2   2    Y    N  NaN
3   2    N    Y    N
4   3    Y    N  NaN
5   3  NaN  NaN    Y

您可以动态创建另一个dict

#check all unique values without column id
print (df.set_index('id').stack(dropna=False).unique())
['Y' 'N' nan]

#create dict for first replace
d = {'Y':1,'N':0, np.nan:-1}
#swap keys, values in dict for another replace
d1 = {v: k for k, v in d.items()}

df1 = df.replace(d).groupby('id').max().replace(d1).reset_index()
print (df1)
   id var1 var2 var3
0   1    Y    N  NaN
1   2    Y    Y    N
2   3    Y    N    Y

EDIT1:

Y - N列中的NaNvar1varN解决方案:

varNAN = 'A'
print (df.fillna(varNAN).groupby('id').max().replace({varNAN:np.nan}).reset_index())
   id var1 var2 var3
0   1    Y    N  NaN
1   2    Y    Y    N
2   3    Y    N    Y

答案 2 :(得分:1)

如果只有' Y',' N'和数据框中的NAN,这是一种更简单的方法。

<强>设置

df = pd.DataFrame({'id': {0: 1, 1: 1, 2: 2, 3: 2, 4: 2},
 'var1': {0: 'Y', 1: 'N', 2: 'Y', 3: 'N', 4: 'Y'},
 'var2': {0: 'N', 1: np.nan, 2: np.nan, 3: 'Y', 4: 'N'},
 'var3': {0: 'Y', 1: 'Y', 2: 'N', 3: 'N', 4: 'Y'}})

Out[45]: 
   id var1 var2 var3
0   1    Y    N    Y
1   1    N  NaN    Y
2   2    Y  NaN    N
3   2    N    Y    N
4   2    Y    N    Y

<强>解决方案

#Fill na with 'A' and get the max (Y>N>A) from each column.
df.fillna('A').groupby('id').max().reset_index()
Out[46]: 
   var1 var2 var3
id               
1     Y    N    Y
2     Y    Y    Y