[英]Pandas DataFrame string replace followed by split and set intersection
我有以下pandas
DataFrame
data = ['18#38#123#23=>21', '18#38#23#55=>35']
d = pd.DataFrame(data, columns = ['rule'])
我有整數列表
r = [18, 55]
如果列表r
中的所有整數也存在於規則中,我想從DataFrame
上方過濾規則。 我嘗試了以下代碼,但失敗了
d[d['rule'].str.replace('=>','#').split('#').astype(set).issuperset(set(r))]
如何使用pandas
實現所需的過濾
您朝着正確的方向前進,只需要使用apply
函數即可:
d[d['rule'].str.replace('=>','#').str.split('#').apply(lambda x: set(x).issuperset(set(map(str,r))))]
我最初的直覺是使用list
理解:
df = pd.DataFrame(['18#38#123#23=>21', '188#38#123#23=>21', '#18#38#23#55=>35'], columns = ['rule'])
def wrap(n):
return r'(?<=[^|^\d]){}(?=[^\d])'.format(n)
patterns = [18, 55]
pd.concat([df['rule'].str.contains(wrap(pattern)) for pattern in patterns], axis=1).all(axis=1)
輸出:
0 False
1 False
2 True
使用str.get_dummies
d.rule.str.replace('=>','#').str.get_dummies(sep='#').loc[:, map(str, r)].all(1)
輸出
0 False
1 True
dtype: bool
詳情:
get_dummies
+ loc
返回
18 55
0 1 0
1 1 1
我的方法類似於@RafaelC的答案,但是將所有string
轉換為int
:
new_df = d.rule.str.replace('=>','#').str.get_dummies(sep='#')
new_df.columns = new_df.columns.astype(int)
has_all = new_df[r].all(1)
# then you can assign new column for initial data frame
d['new_col'] = 10
d.loc[has_all, 'new_col'] = 100
輸出:
+-------+-------------------+------------+
| | rule | new_col |
+-------+-------------------+------------+
| 0 | 18#38#123#23=>21 | 10 |
| 1 | 188#38#23#55=>35 | 10 |
| 2 | 18#38#23#55=>35 | 100 |
+-------+-------------------+------------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.