如何通过熊猫过滤满足正则表达式的行
Posted
技术标签:
【中文标题】如何通过熊猫过滤满足正则表达式的行【英文标题】:how to filter rows that satisfy a regular expression via pandas 【发布时间】:2017-07-13 01:28:34 【问题描述】:我正在尝试找出一种方法,通过 Pandas 仅选择满足我的正则表达式的行。我的实际数据集 data.csv 有一列(标题未标记)和数百万行。前四行如下所示:
5;4Z13H;;L
5;346;4567;;O
5;342;4563;;P
5;3LPH14;4567;;O
我写了下面的正则表达式
([1-9][A-Z](.*?);|[A-Z][A-Z](.*?);|[A-Z][1-9](.*?);)
它将从第 1 行识别 4Z13H;
和从第 4 行识别 3LPH14;
。基本上我希望 pandas 过滤我的数据并选择第 1 行和第 4 行。
所以我想要的输出是
5;4Z13H;;L
5;3LPH14;4567;;O
然后,我想将过滤器行的子集保存到新的 csv、filteredData.csv 中。到目前为止我只有这个:
import pandas as pd
import numpy as np
import sys
import re
sys.stdout=open("filteredData.csv","w")
def Process(filename, chunksize):
for chunk in pd.read_csv(filename, chunksize=chunksize):
df[0] = df[0].re.compile(r"([1-9][A-Z]|[A-Z][A-Z]|[A-Z][1-9])(.*?);")
sys.stdout.close()
if __name__ == "__main__":
Process('data.csv', 10 ** 4)
我对 python 还是比较陌生,所以上面的代码有一些语法问题(我还在试图弄清楚如何使用 pandas chunksize)。然而,主要问题是通过正则表达式过滤行。非常感谢任何人的建议
【问题讨论】:
【参考方案1】:一种方法是将 csv 读取为 pandas 数据框,然后使用 str.contains 创建掩码列
df['mask'] = df[0].str.contains('(\d+[A-Z]+\d+)') #0 is the column name
df = (df[df['mask'] == True]).drop('mask', axis = 1)
您会得到所需的数据帧,如果您愿意,可以使用 df = df.reset_index() 重置索引
0
0 5;4Z13H;;L
3 5;3LPH14;4567;;O
其次是首先读取csv并创建一个仅包含过滤行的编辑文件,然后读取过滤后的csv以创建数据框
with open('filteredData.csv', 'r') as f_in:
with open('filteredData_edit.csv', 'w') as f_outfile:
f_out = csv.writer(f_outfile)
for line in f_in:
line = line.strip()
row = []
if bool(re.search("(\d+[A-Z]+\d+)", line)):
row.append(line)
f_out.writerow(row)
df = pd.read_csv('filteredData_edit.csv', header = None)
你得到
0
0 5;4Z13H;;L
1 5;3LPH14;4567;;O
根据我的经验,我更喜欢第二种方法,因为在创建数据框之前过滤掉不需要的行会更有效。
【讨论】:
感谢您的回答。但是,如何在保留行中包含的其他数据的同时做到这一点?因此,我没有使用0 4Z13
和3 3LPH14
,而是尝试使用5;4Z13H;;L
和5;3LPH14;4567;;O
这很棒,为我指明了正确的方向。对于其他人,您可以将布尔值存储在他们自己的变量中,与df
分开。换句话说,mask = df[0].str...
,然后是df = df[mask]
。然后,您不会添加一列只是为了按它过滤并删除它。以上是关于如何通过熊猫过滤满足正则表达式的行的主要内容,如果未能解决你的问题,请参考以下文章
Python Datatable/Pydatatable:如何通过正则表达式过滤数据表中的行并根据过滤器为新变量赋值
如何使用正则表达式或熊猫过滤 NLTK 的 FreqDist 计数器