在Python中的Stack操作期间保留少量NA,并删除其余NA

时间:2019-07-31 07:44:51

标签: python pandas dataframe

我有一个如下所示的数据框

df2 = pd.DataFrame({'person_id':[1],'H1_date' : ['2006-10-30 00:00:00'], 'H1':[2.3],'H2_date' : ['2016-10-30 00:00:00'], 'H2':[12.3],'H3_date' : ['2026-11-30 00:00:00'], 'H3':[22.3],'H4_date' : ['2106-10-30 00:00:00'], 'H4':[42.3],'H5_date' : [np.nan], 'H5':[np.nan],'H6_date' : ['2006-10-30 00:00:00'], 'H6':[2.3],'H7_date' : [np.nan], 'H7':[2.3],'H8_date' : ['2006-10-30 00:00:00'], 'H8':[np.nan]})

enter image description here

如上面的屏幕快照所示,我的源datframe(df2)包含几个NA's

当我做df2.stack()时,我丢失了数据中的所有NA。

但是我想保留H7_dateH8的NA,因为它们具有相应的值/日期对。对于H7_date,我有一个有效值H7,对于H8,我有一个对应的H8_date

我只想在两个值(H5_dateH5)均为NA时才删除记录。

请注意,这里我只有很少的列,而我的真实数据有150多个列,并且列名是事先未知的。

我希望我的输出如下所示,虽然它们是NA的,但没有H5_dateH5

enter image description here

3 个答案:

答案 0 :(得分:1)

您可以使用:

col = [x for x in df.columns if "date" in x] for column in col: df.dropna(subset=[column,column[:-4]], how = 'all',inplace=True)

subset将选择检测到NA的行,how指定该行的条件(此处2行中的所有行都必须为NA),inplace修改当前行数据框

答案 1 :(得分:1)

尝试pd.DataFrame.melt

df = pd.melt(df2, id_vars='person_id', var_name='col', value_name='dates')
df['col2'] = df['col'].str.split("_").str[0]
df['count'] = df.groupby(['col2'])['dates'].transform(pd.Series.count)
df = df[df['count'] != 0]
df.drop(['col2', 'count'], axis=1, inplace=True)
print(df)
    person_id      col                dates
0           1  H1_date  2006-10-30 00:00:00
1           1       H1                  2.3
2           1  H2_date  2016-10-30 00:00:00
3           1       H2                 12.3
4           1  H3_date  2026-11-30 00:00:00
5           1       H3                 22.3
6           1  H4_date  2106-10-30 00:00:00
7           1       H4                 42.3
10          1  H6_date  2006-10-30 00:00:00
11          1       H6                  2.3
12          1  H7_date                  NaN
13          1       H7                  2.3
14          1  H8_date  2006-10-30 00:00:00
15          1       H8                  NaN

答案 2 :(得分:1)

一种方法是融化DF,应用标识同一“组”中列的键(在这种情况下为H<some digits>,但您可以根据需要进行修改),然后按人员分组并对该键进行过滤那些包含至少一个非NA值的组),例如:

开始于:

df = pd.DataFrame({'person_id':[1],'H1_date' : ['2006-10-30 00:00:00'], 'H1':[2.3],'H2_date' : ['2016-10-30 00:00:00'], 'H2':[12.3],'H3_date' : ['2026-11-30 00:00:00'], 'H3':[22.3],'H4_date' : ['2106-10-30 00:00:00'], 'H4':[42.3],'H5_date' : [np.nan], 'H5':[np.nan],'H6_date' : ['2006-10-30 00:00:00'], 'H6':[2.3],'H7_date' : [np.nan], 'H7':[2.3],'H8_date' : ['2006-10-30 00:00:00'], 'H8':[np.nan]})

使用:

df2 = (
    df.melt(id_vars='person_id')
    .assign(_gid=lambda v: v.variable.str.extract('H(\d+)'))
    .groupby(['person_id', '_gid'])
    .filter(lambda g: bool(g.value.any()))
    .drop('_gid', 1)
)

哪个给你:

    person_id variable                value
0           1  H1_date  2006-10-30 00:00:00
1           1       H1                  2.3
2           1  H2_date  2016-10-30 00:00:00
3           1       H2                 12.3
4           1  H3_date  2026-11-30 00:00:00
5           1       H3                 22.3
6           1  H4_date  2106-10-30 00:00:00
7           1       H4                 42.3
10          1  H6_date  2006-10-30 00:00:00
11          1       H6                  2.3
12          1  H7_date                  NaN
13          1       H7                  2.3
14          1  H8_date  2006-10-30 00:00:00
15          1       H8                  NaN

然后,您可以根据需要将其用作调整的起点。