我有一个数据集,其中包含来自web服务的匿名搜索数据。我希望看到哪些搜索词是最常用的,但不会导致点击。然而,数据的结构方式我很难处理,所以我需要先削减它-但我能想到的唯一方法是缓慢和低效的,我对它的了解不够,无法通过搜索找到可用的答案。
我不知道数据是如何收集的,但大多数情况下,每次击键似乎都会生成一个新行-尽管有时一个单词出现在列表中,大部分或完全形成(可能是复制/粘贴?)。
一个例子:
date , searchTerm
26-04-2022 13:30:30, d
26-04-2022 13:30:30, de
26-04-2022 13:30:31, dep
26-04-2022 13:30:31, depa
26-04-2022 13:30:31, depar
26-04-2022 13:30:32, depart
26-04-2022 13:30:32, departm
26-04-2022 13:30:33, departme
26-04-2022 13:30:34, departmen
26-04-2022 13:30:34, department
26-04-2022 13:30:34, departmen
26-04-2022 13:30:35, departme
26-04-2022 13:30:36, departm
...
26-04-2022 13:32:11, somethi
26-04-2022 13:32:31, somethin
26-04-2022 13:32:31, something
26-04-2022 13:32:56, another word
...
在这个列表中,我想只保留说26-04-2022 13:30:34, department
,26-04-2022 13:32:31, something
和26-04-2022 13:32:56, another word
的行,但我能想到的唯一方法是遍历列表,删除包含在相邻行中的字符串行。
我相当确信这不是"正确的"。不过这是一种方法。这不是我必须经常做的事情,但如果有更好(或"正确")的方法,我宁愿学一些新的东西。
我们可以使用pandas.Series.shift
来比较行与相邻行,并使用python内置运算符in
来测试子字符串是否包含。
import pandas as pd
df = pd.DataFrame({'date': range(7), 'searchTerm': 'departme departmen department departmen somethin something anotherword'.split()})
print(df)
# date searchTerm
# 0 0 departme
# 1 1 departmen
# 2 2 department
# 3 3 departmen
# 4 4 somethin
# 5 5 something
# 6 6 anotherword
goodrows = [(x not in y and x not in z) for x, y, z in zip(df['searchTerm'], df['searchTerm'].shift(-1, fill_value=''), df['searchTerm'].shift(1, fill_value=''))]
print( df[goodrows] )
# date searchTerm
# 2 2 department
# 5 5 something
# 6 6 anotherword
不得不使用列表推导式有点令人沮丧。Pandas允许很多很酷的符号来操作数字,但对于字符串就不那么多了。
例如:
goodrows = not (df['searchTerm'] <= df['searchTerm'].shift(-1) or df['searchTerm'] <= df['searchTerm'].shift(1))
print( df[goodrows] )
如果searchTerm是数字,并且我们想要删除小于相邻行的行,可以工作。
但是我们不能用操作符in
或方法str.contains
来替换操作符<=
,以使其在字符串上工作。