【问题标题】:Python pandas how to scan string contains by row?Python pandas如何按行扫描字符串包含?
【发布时间】:2018-03-16 15:44:39
【问题描述】:

如果 pandas 数据框行包含某个子字符串,如何扫描?

例如,我有一个包含 11 列的数据框 所有列都包含名称

ID    name1     name2       name3      ...    name10
-------------------------------------------------------
AA    AA_balls  AA_cakee1  AA_lavender ...   AA_purple
AD    AD_cakee  AD_cats    AD_webss    ...   AD_ballss
CS    CS_cakee  CS_cats    CS_webss    ...   CS_purble
.
.
.

我想在数据框中获取包含“球”的行并获取 ID

所以结果将是 ID 'AA' 和 ID 'AD',因为 AA_balls 和 AD_ballss 在行中。

我在 google 上搜索过,但似乎没有针对这些的具体结果。 人们通常会询问有关在特定列而不是所有列(单行)中搜索子字符串的问题

df[df["col_name"].str.contains("ball")]

我想到的方法如下,时间不多的可以跳过:

(1) 遍历列

for col_name in col_names:
     df.append(df[df[col_name].str.contains('ball')])

然后删除具有相同 ID 值的重复行 但是这种方法会很慢

(2) 通过将 name2-name10 列附加到一列中,将数据框制作为 2 列数据框,并使用 df[df["concat_col"].str.contains("ball")]["ID] 获取ID 和删除重复项

ID  concat_col   
AA    AA_balls 
AA    AA_cakeee
AA    AA_lavender
AA    AA_purple
 .
 .
 .
CS   CS_purble

(3) 使用像 (2) 这样的数据框来制作字典 在哪里

 dict[df["concat_col"].value] = df["ID"]

然后得到

[value for key, value in programs.items() if 'ball' in key()]

但在这种方法中,我需要遍历字典并变慢

如果有一种方法可以让我在没有这些过程的情况下更快地应用, 我宁愿这样做。 如果有人知道这件事, 如果您能告诉我,将不胜感激:) 谢谢!

【问题讨论】:

  • DataFrame 的大小是多少?
  • 不大,df.shape 在 (4000, 13) 附近,但我在编程过程中做了很多预处理,想寻找更省时的方法
  • 好的,给我一些时间安排
  • 嗯,时间也取决于有多少场比赛显然 - 你怎么看? 50% 行数?还是别的什么?
  • 感谢您在下面的回答。让我试试并回复你。匹配项很少,少于 15 行。

标签: python pandas


【解决方案1】:

一个想法是使用melt:

df = df.melt('ID')

a = df.loc[df['value'].str.contains('ball'), 'ID']
print (a)
0     AA
10    AD
Name: ID, dtype: object

另一个:

df = df.set_index('ID')
a = df.index[df.applymap(lambda x: 'ball' in x).any(axis=1)]

或者:

mask = np.logical_or.reduce([df[x].str.contains('ball', regex=False) for x in df.columns])
a = df.loc[, 'ID']

时间安排

np.random.seed(145)
L = list('abcdefgh')
df = pd.DataFrame(np.random.choice(L, size=(4000, 10)))
df.insert(0, 'ID', np.arange(4000).astype(str))
a = np.random.randint(4000, size=15)
b = np.random.randint(1, 10, size=15)
for i, j in zip(a,b):
    df.iloc[i, j] = 'AB_ball_DE'
#print (df)


In [85]: %%timeit
    ...: df1 = df.melt('ID')
    ...: a = df1.loc[df1['value'].str.contains('ball'), 'ID']
    ...: 
10 loops, best of 3: 24.3 ms per loop

In [86]: %%timeit
    ...: df.loc[np.logical_or.reduce([df[x].str.contains('ball', regex=False) for x in df.columns]), 'ID']
    ...: 
100 loops, best of 3: 12.8 ms per loop

In [87]: %%timeit
    ...: df1 = df.set_index('ID')
    ...: df1.index[df1.applymap(lambda x: 'ball' in x).any(axis=1)]
    ...: 
100 loops, best of 3: 11.1 ms per loop

【讨论】:

  • 谢谢你的回答很好!!之前不知道融化的方法。并且需要了解更多关于 lambda 和 applymap...
【解决方案2】:

也许这可行?

mask = df.apply(lambda row: row.map(str).str.contains('word').any(), axis=1)
df.loc[mask]

免责声明:我没有对此进行测试。也许.map(str) 不是必需的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多