[英]how to drop rows based on some condition about the content in pandas dataframe
我想从数据框中删除一些行(从 .txt 文件中读取)。 换句话说,我只想保留有趣的行。 我的数据框如下所示:
data
0 ID-0123456789 #ID I need
1 AG-TH/RGS_Srbcd_675F9_TRL #randrom text I dont need
2 15.00 #value I need (belongs to ID above)
3 NDFSD/+vbdgfnhj_46/THS #randrom text I dont need
4 Sgbfd_FG-fdg_GRT/DR.x #randrom text I dont need
5 ID-1234567890 #ID I need
6 3_F/H_ & S/J #randrom text I dont need
7 0.00 #value I need (belongs to ID above)
... ... ...
没有模式,有时会有更多“我不需要的随机文本”行,有时没有。 我尝试根据内容删除行,例如保留df["data"].str.startswith("ID")
保留 ID... 行,但我丢失了值。 我尝试将其与type()
结合使用,但列中的值也是字符串。 我的下一个想法是关注数字,但“我不需要的随机文本”行在某些情况下也包含数字。 在删除不必要的行后,我想得到这样的 df:
data
0 ID-0123456789 #ID I need
2 15.00 #value I need (belongs to ID above)
5 ID-1234567890 #ID I need
7 0.00 #value I need (belongs to ID above)
... ... ...
任何的想法? 如果 ID 和值位于不同的列中,这不是问题,实际上我的目标是最终获得:
ID value
0 ID-0123456789 15.00
1 ID-1234567890 0.00
...
先感谢您! 对不起,如果很明显,我是 python 和编程的新手。
这是一个可能有效的“脏”解决方案(取决于框架中的实际内容):
data = [
'ID-0123456789',
'AG-TH/RGS_Srbcd_675F9_TRL',
15.00,
'NDFSD/+vbdgfnhj_46/THS',
'Sgbfd_FG-fdg_GRT/DR.x',
'ID-1234567890',
'3_F/H_ & S/J',
0.00,
]
df = pd.DataFrame(data, columns=['data'])
df = pd.concat(
[pd.DataFrame(df[df['data'].apply(lambda x: str(x)[:3]) == 'ID-'].values, columns=['ID']),
pd.DataFrame(df[df['data'].apply(type) == float].values, columns=['value'])],
axis=1)
或者(看起来更文明一点):
df = pd.DataFrame(zip(df[df['data'].apply(lambda x: str(x)[:3]) == 'ID-']['data'],
df[df['data'].apply(type) == float]['data']),
columns=['ID', 'value'])
输出:
ID value
0 ID-0123456789 15
1 ID-1234567890 0
如果某些随机文本有可能以ID-
开头,那么这样的操作会更安全:
import re
re_id = re.compile(r'^ID-\d{10}$')
def is_id(obj):
return bool(re_id.match(str(obj).strip()))
df = pd.DataFrame(zip(df[df['data'].apply(is_id)]['data'],
df[df['data'].apply(type) == float]['data']),
columns=['ID', 'value'])
一些评论:
DataFrame/Series 的apply方法在这里“应用”
df['data'].apply(is_id)
函数is_id
到每一行,即单个元素,因为df['data']
是一个系列。 结果是一系列bool
值,找到 ID 时为True
,否则为False
:
0 True
1 False
2 False
3 False
4 False
5 True
6 False
7 False
如果您将此系列“插入”到原始框架df[...]
每一行带有相应的False
都会被丢弃。
内置的zip函数将可迭代对象“配对”成一个迭代器。 为了说明它的作用:
list(zip([1, 2, 3, 4], ['a', 'b', 'c', 'd']))
造成
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
您可以将它与任意数量的可迭代对象一起使用。
随机文本总是相同的吗? 如果是这样,您可以尝试:
#converting to a series, finding the ones that match, and adding back to the table
find_text = df['data']
#create series that has 0 for what matches the ads
text_found = find_Ads.str.find("random text I don't need")
#add column to table with 0's
df['Random'] = text_found
#create new table with those rows with zero gone
df = df[df['Random'] != 1].reset_index(drop=True)
这将创建一个系列,用您的随机文本查找每一行并将其分配为 1。然后您可以将该系列作为新列添加到您的原始框架中,然后仅过滤未找到的行细绳。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.