根据给定条件过滤数据框并添加新列
Posted
技术标签:
【中文标题】根据给定条件过滤数据框并添加新列【英文标题】:Filter a data-frame and add a new column according to the given condition 【发布时间】:2019-09-30 17:19:24 【问题描述】:我有一个这样的数据框
ID col1 col2
1 Abc street 2017-07-27
1 None 2017-08-17
1 Def street 2018-07-15
1 None 2018-08-13
2 fbg street 2018-01-07
2 None 2018-08-12
2 trf street 2019-01-15
我想过滤掉 col1 中的所有 'None' 并将相应的 col2 值添加到新列 col3 中。我的输出是这样的
ID col1 col2 col3
1 Abc street 2017-07-27 2017-08-17
1 Def street 2018-07-15 2018-08-13
2 fbg street 2018-01-07 2018-08-12
2 trf street 2019-01-15
谁能帮我实现这个目标。
【问题讨论】:
是None
还是'None'
?
哦!!。它实际上是“无”
【参考方案1】:
试试:
filters = df['col1'].isna()
s = df.loc[filters, 'col2'].copy()
df = df[~filters]
df['col3'] = s.values
编辑:正如你所说,你想要的过滤器是'None'
,而不是None
,那么:
filters = df['col1'].eq('None')
【讨论】:
也许你需要检查一些边缘情况,我认为ID是分配的关键,如果你只按值分配,ID可能不匹配 同意@WeNYoBen,这对paste
将值作为一列很危险
确实如此。但是给定的ID
列不是唯一值,因此对其进行分配会失败(我认为)。或者我需要做一个 groupby。【参考方案2】:
使用ffill
+ pivot_table
。这假定 None
遵循正确的值,从您的数据中可以看出。
u = df.assign(col1=df.col1.replace('None'))
g = ['ID', 'col1']
idx = u.groupby(g).cumcount()
(u.assign(idx=idx)
.pivot_table(index=g, columns='idx', values='col2', aggfunc='first')
.reset_index())
idx ID col1 0 1
0 1 Abc street 2017-07-27 2017-08-17
1 1 Def street 2018-07-15 2018-08-13
2 2 fbg street 2018-01-07 2018-08-12
3 2 trf street 2019-01-15 NaN
【讨论】:
【参考方案3】:我正在使用cumcount
和merge
df1=df.loc[df.col1.ne('None'),:].copy()
df2=df.loc[df.col1.eq('None'),:].copy()
df1['Key']=df1.groupby('ID').cumcount()
df2['Key']=df2.groupby('ID').cumcount()
df1.merge(df2.drop('col1',1),on=['ID','Key'],how='left')
Out[816]:
ID col1 col2_x Key col2_y
0 1 Abcstreet 2017-07-27 0 2017-08-17
1 1 Defstreet 2018-07-15 1 2018-08-13
2 2 fbgstreet 2018-01-07 0 2018-08-12
3 2 trfstreet 2019-01-15 1 NaN
【讨论】:
【参考方案4】:今天的 Over Engineered with Numpy 版本
虽然 Numpy 不可否认地非常不明显
i, rows = pd.factorize([*zip(df.ID, df.col1.replace('None'))])
k, cols = pd.factorize(df.groupby(i).cumcount())
dleft = pd.DataFrame(dict(zip(['ID', 'col1'], zip(*rows))))
drigt = pd.DataFrame(index=dleft.index, columns=np.arange(len(cols)) + 2).add_prefix('col')
drigt.values[i, k] = df.col2.values
dleft.join(drigt)
ID col1 col2 col3
0 1 Abc street 2017-07-27 2017-08-17
1 1 Def street 2018-07-15 2018-08-13
2 2 fbg street 2018-01-07 2018-08-12
3 2 trf street 2019-01-15 NaN
【讨论】:
【参考方案5】:又一次尝试:
f=df['col1']=='None'
c3=df.loc[f].col2.reset_index(drop=True)
df=df[~f]
df2=pd.concat([df.reset_index(drop=True),c3], axis=1, ignore_index=True)
df2.columns=['ID', 'col1', 'col2', 'col3']
ID col1 col2 col3
0 1 Abc street 2017-07-27 2017-08-17
1 1 Def street 2018-07-15 2018-08-13
2 2 fbg street 2018-01-07 2018-08-12
3 2 trf street 2019-01-15 NaN
【讨论】:
以上是关于根据给定条件过滤数据框并添加新列的主要内容,如果未能解决你的问题,请参考以下文章