我有一个包含 99 列 dx1-dx99 和 99 列 px1-px99 的 Pandas 数据框。这些列的内容是 4 到 8 个字符和数字的不同长度的代码。
我只想从这些列中过滤那些内容,其中这些内容的前三个字符与提供的列表中的三个字符匹配。提供的列表包含只有三个字符的字符串。
我动态生成的提供列表的长度非常长。因此我必须传递整个列表而不是作为单独的字符串。
例如,我有这个数据框:
df = pd.DataFrame({'A': 'foo bar one123 bar foo one324 foo 0'.split(),
'B': 'one546 one765 twosde three twowef two234 onedfr three'.split(),
'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
A B C D
0 foo one546 0 0
1 0 one765 1 2
2 one123 twosde 2 4
3 bar three 3 6
4 foo twowef 4 8
5 one324 two234 5 10
6 foo onedfr 6 12
7 0 three 7 14
填充的单元格是对象类型,所有零最初都是 NULL,我用 pd.fillna(0) 填充了零。
当我这样做时:
keep = df.iloc[:,:].isin(['one123','one324','twosde','two234']).values
df.iloc[:,:] = df.iloc[:,:].where(keep, 0)
print(df)
我明白了:
A B C D
0 0 0 0 0
1 0 0 0 0
2 one123 twosde 0 0
3 0 0 0 0
4 0 0 0 0
5 one324 two234 0 0
6 0 0 0 0
7 0 0 0 0
但我不想传递单个字符串 'one123'、'one324'、'twosde'、'two234',而是想传递一个包含部分字符串的列表,如下所示:
startstrings = ['one', 'two']
keep = df.iloc[:,:].contains(startstrings)
df.iloc[:,:] = df.iloc[:,:].where(keep, 0)
print(df)
但是上面的不行。我想保留所有以“一”或“二”开头的内容。
知道如何实现吗?我的数据集很大,因此效率很重要。
最佳答案
pandas str.contains
接受正则表达式,让您可以测试列表中的任何项目。遍历每一列并使用 str.contains:
startstrings = ['one', 'two']
pattern = '|'.join(startstrings)
for col in df:
if all(df[col].apply(type) == str):
#Set any values to 0 if they don't contain value
df.ix[~df[col].str.contains(pattern), col] = 0
else:
#Column is not all strings
df[col] = 0
产生:
A B C D
0 0 one1 0 0
1 0 one1 0 0
2 one1 two1 0 0
3 0 0 0 0
4 0 two1 0 0
5 one1 two1 0 0
6 0 one1 0 0
7 0 0 0 0
关于python - 根据列表中的部分字符串过滤 Pandas (python)数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43189507/