在 python 中切片 Not NaN 值
Slicing Not NaN values in python
我是 python 新手,希望得到一些帮助!
我有一个名为 result 的数据框,格式如下:
start end rf1 rf2 rf3
01-01-2008 10-01-2008 nan 12 nan
02-01-2008 11-01-2008 nan 16 nan
03-01-2008 12-01-2008 32 18 18
我想要每行中不是 NaN 的那些 rf 的列表。请注意,我的前两列不是索引。我尝试了以下代码但无法得到答案:
result_2=result.dropna(axis=1,how='all')
基本上我想要一个 rfs 不是 NaN 的日期列表。
例如,在第一行中,我的输出应该给出开始日期、结束日期和 'rf2',同样在最后一行中,我的输出应该给出开始日期、结束日期、'rf1'、'rf2' ,'rf3'
IIUC 您可以使用 stack
过滤 rfX
列,groupby
索引并从结果组构建列表:
df.filter(regex=r'rf\d').stack().groupby(level=0).agg(list)
0 [12.0]
1 [16.0]
2 [32.0, 18.0, 18.0]
dtype: object
或使用列表理解:
[[i for i in row if i==i] for row in df.filter(regex=r'rf\d').values.tolist()]
[[12.0], [16.0], [32.0, 18.0, 18.0]]
或者如果您需要列名。
df['vals'] = df.filter(regex=r'rf\d').stack().reset_index(level=1)\
.groupby(level=0).level_1.agg(list)
print(df)
start end rf1 rf2 rf3 vals
0 2008-01-01 2008-10-01 NaN 12 NaN [rf2]
1 2008-02-01 2008-11-01 NaN 16 NaN [rf2]
2 2008-03-01 2008-12-01 32.0 18 18.0 [rf1, rf2, rf3]
一个选项是列表理解:
[[x1 for x1 in x if pd.notnull(x1)] for x in df[['rf1', 'rf2', 'rf3']].values]
IIUC,可以使用pd.melt
和join
s = (
pd.melt(df, id_vars=["start", "end"])
.dropna()
.groupby(["start", "end"])["variable"]
.agg(list)
.to_frame("vals")
)
df1 = df.set_index(['start','end']).join(s)
print(df1)
rf1 rf2 rf3 vals
start end
2008-01-01 2008-10-01 NaN 12 NaN [rf2]
2008-02-01 2008-11-01 NaN 16 NaN [rf2]
2008-03-01 2008-12-01 32.0 18 18.0 [rf1, rf2, rf3]
使用the.select_dtypes排除不需要的列并查找剩余满足条件的列
df2=df.select_dtypes(exclude='object').notna()#Excludes the dates
将列转换为 numpy 数组
t=df2.columns.to_numpy()
生成一个系列,其中列布尔值选择为非空并加入 df
df.join(pd.DataFrame({'listofcols':[t[i] for i in df2.to_numpy()]}))
start end rf1 rf2 rf3 listofcols
0 01-01-2008 10-01-2008 NaN 12 NaN [rf2]
1 02-01-2008 11-01-2008 NaN 16 NaN [rf2]
2 03-01-2008 12-01-2008 32.0 18 18.0 [rf1, rf2, rf3]
如果对通用列表或数据框中所有不为空的列感兴趣
df.notna().any(0).index.tolist()#find any nan on taxis=0 and add to list
['start', 'end', 'rf1', 'rf2', 'rf3']
我是 python 新手,希望得到一些帮助! 我有一个名为 result 的数据框,格式如下:
start end rf1 rf2 rf3
01-01-2008 10-01-2008 nan 12 nan
02-01-2008 11-01-2008 nan 16 nan
03-01-2008 12-01-2008 32 18 18
我想要每行中不是 NaN 的那些 rf 的列表。请注意,我的前两列不是索引。我尝试了以下代码但无法得到答案:
result_2=result.dropna(axis=1,how='all')
基本上我想要一个 rfs 不是 NaN 的日期列表。 例如,在第一行中,我的输出应该给出开始日期、结束日期和 'rf2',同样在最后一行中,我的输出应该给出开始日期、结束日期、'rf1'、'rf2' ,'rf3'
IIUC 您可以使用 stack
过滤 rfX
列,groupby
索引并从结果组构建列表:
df.filter(regex=r'rf\d').stack().groupby(level=0).agg(list)
0 [12.0]
1 [16.0]
2 [32.0, 18.0, 18.0]
dtype: object
或使用列表理解:
[[i for i in row if i==i] for row in df.filter(regex=r'rf\d').values.tolist()]
[[12.0], [16.0], [32.0, 18.0, 18.0]]
或者如果您需要列名。
df['vals'] = df.filter(regex=r'rf\d').stack().reset_index(level=1)\
.groupby(level=0).level_1.agg(list)
print(df)
start end rf1 rf2 rf3 vals
0 2008-01-01 2008-10-01 NaN 12 NaN [rf2]
1 2008-02-01 2008-11-01 NaN 16 NaN [rf2]
2 2008-03-01 2008-12-01 32.0 18 18.0 [rf1, rf2, rf3]
一个选项是列表理解:
[[x1 for x1 in x if pd.notnull(x1)] for x in df[['rf1', 'rf2', 'rf3']].values]
IIUC,可以使用pd.melt
和join
s = (
pd.melt(df, id_vars=["start", "end"])
.dropna()
.groupby(["start", "end"])["variable"]
.agg(list)
.to_frame("vals")
)
df1 = df.set_index(['start','end']).join(s)
print(df1)
rf1 rf2 rf3 vals
start end
2008-01-01 2008-10-01 NaN 12 NaN [rf2]
2008-02-01 2008-11-01 NaN 16 NaN [rf2]
2008-03-01 2008-12-01 32.0 18 18.0 [rf1, rf2, rf3]
使用the.select_dtypes排除不需要的列并查找剩余满足条件的列
df2=df.select_dtypes(exclude='object').notna()#Excludes the dates
将列转换为 numpy 数组
t=df2.columns.to_numpy()
生成一个系列,其中列布尔值选择为非空并加入 df
df.join(pd.DataFrame({'listofcols':[t[i] for i in df2.to_numpy()]}))
start end rf1 rf2 rf3 listofcols
0 01-01-2008 10-01-2008 NaN 12 NaN [rf2]
1 02-01-2008 11-01-2008 NaN 16 NaN [rf2]
2 03-01-2008 12-01-2008 32.0 18 18.0 [rf1, rf2, rf3]
如果对通用列表或数据框中所有不为空的列感兴趣
df.notna().any(0).index.tolist()#find any nan on taxis=0 and add to list
['start', 'end', 'rf1', 'rf2', 'rf3']