如何拆分和分类 pandas 数据框的列中的值

how to split and categorize value in a column of a pandas dataframe

我有df,

    keys
0   one
1   two,one
2   " "
3   five,one
4   " "
5   two,four
6   four
7   four,five

和两个列表,

 actual=["one","two"]
 syn=["four","five"]

我正在创建一个新行 df["val"] 我正在尝试获取 df["keys"] 中的单元格类别。如果 actual 中存在任何键,那么我想在同一行的新列中添加实际值,如果实际中不存在任何值,那么我想要相应的 df["val"] as syn。它不应该对白色 space 单元格执行任何操作。

我想要的输出是,

output_df

    keys      val
0   one       actual
1   two,one   actual
2   " "        
3   five,one  actual
4   " "
5   two,four  actual
6   four      syn
7   four,five syn

请帮忙,提前致谢!

首先,按逗号拆分并将单词扩展到它们自己的单元格中。

v = df['keys'].str.split(',',expand=True)

接下来,使用 isin + any 形成两个掩码,一个用于 actual,另一个用于 syn。这些将用于标记行。

m1 = v.isin(["one","two"]).any(1)
m2 = v.isin(["four","five"]).any(1)

最后,使用 np.selectnp.where 根据计算出的掩码标记行。

df['val'] = np.select([m1, m2], ['actual', 'syn'], default='')

或者,

df['val'] = np.where(m1, 'actual', np.where(m2, 'syn', ''))

df

        keys     val
0        one  actual
1    two,one  actual
2                   
3   five,one  actual
4                   
5   two,four  actual
6       four     syn
7  four,five     syn

详情

v

      0     1
0   one  None
1   two   one
2        None
3  five   one
4        None
5   two  four
6  four  None
7  four  five

m1

0     True
1     True
2    False
3     True
4    False
5     True
6    False
7    False
dtype: bool

m2

0    False
1    False
2    False
3     True
4    False
5     True
6     True
7     True
dtype: bool

np.select([m1, m2], ['actual', 'syn'], default='')
array(['actual', 'actual', '', 'actual', '', 'actual', 'syn', 'syn'],
      dtype='<U6')

使用具有双重条件的 numpy.select 通过比较 sets:

检查成员资格
s = df['keys'].str.split(',')
m1 = s.apply(set) & set(actual)
m2 = s.apply(set) & set(syn)

df['part'] = np.select([m1, m2], ['actual','syn'], default='')
print (df)
        keys    part
0        one  actual
1    two,one  actual
2                   
3   five,one  actual
4                   
5   two,four  actual
6       four     syn
7  four,five     syn

时间:

df = pd.concat([df] * 10000, ignore_index=True)


In [143]: %%timeit 
     ...: s = df['keys'].str.split(',')
     ...: m1 = s.apply(set) & set(actual)
     ...: m2 = s.apply(set) & set(syn)
     ...: 
1 loop, best of 3: 160 ms per loop

#cᴏʟᴅsᴘᴇᴇᴅ' s solution
In [144]: %%timeit
     ...: v = df['keys'].str.split(',',expand=True)
     ...: m1 = v.isin(["one","two"]).any(1)
     ...: m2 = v.isin(["four","five"]).any(1)
     ...: 
1 loop, best of 3: 193 ms per loop

警告

性能真的取决于数据。