我有一個包含多列的資料框,例如:
Name Age Fname
0 Alex 10 Alice
1 Bob 12 Bob
2 Clarke 13 clarke
我的過濾條件是檢查是否Name是(不區分大小寫的)相應Fname.
如果是平等,那么簡單的事情就是:
df[df["Name"].str.lower() == df["Fname"].str.lower()]
作品。但是,我想要子字串匹配,所以不是==,我認為in會起作用。但這會產生錯誤,因為它將其中一個引數解釋為pd.Series。我的第一個問題是Why this difference in interpretation?
我嘗試的另一種方法是使用.str.contains:
df[df["Fname"].str.contains(df["Name"], case=False)]
它也解釋df["Name"]為pd.Series,當然,適用于引數中的一些 const 字串。
eg. this works:
df[df["Fname"].str.contains("a", case=False)]
我想解決這種情況,所以在這方面的任何幫助表示贊賞。
uj5u.com熱心網友回復:
.str 訪問器非常復雜且緩慢。大多數時候最好使用串列理解。
import pandas as pd
import numpy as np
import timeit
import matplotlib.pyplot as plt
import pandas.testing as pt
def list_comprehension_lower(df):
return df[[len(set(i)) == 1 for i in (zip([x.lower() for x in df['Name']],[y.lower() for y in df['Fname']]))]]
def apply_axis_1_lower(df):
return df[df.apply(lambda x: x['Name'].lower() in x['Fname'].lower(), axis=1)]
def dot_string_lower(df):
return df[df["Name"].str.lower() == df["Fname"].str.lower()]
fig, ax = plt.subplots()
res = pd.DataFrame(
index=[1, 5, 10, 30, 50, 100, 300, 500, 700, 1000, 10000],
columns='list_comprehension_lower apply_axis_1_lower dot_string_lower'.split(),
dtype=float
)
for i in res.index:
d = pd.concat([df]*i, ignore_index=True)
for j in res.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
res.at[i, j] = timeit.timeit(stmt, setp, number=100)
res.groupby(res.columns.str[4:-1], axis=1).plot(loglog=True, ax=ax);
輸出:

現在,回到你原來的問題,你可以使用 list_comprehensionzip和in:
df.loc[2, 'Fname'] = ' Adams'
df[[x in y for x, y in zip([x.lower() for x in df['Name']],[y.lower() for y in df['Fname']])]]
輸出:
Name Age Fname
1 Bob 12 Bob
2 Clarke 13 clarke Adams
uj5u.com熱心網友回復:
您可以遍歷索引軸:
>>> df[df.apply(lambda x: x['Name'].lower() in x['Fname'].lower(), axis=1)]
Name Age Fname
1 Bob 12 Bob
2 Clarke 13 clarke
str.contains在第一個引數中采用常量而pat不是 a Series。
uj5u.com熱心網友回復:
您可以使用.apply()withaxis=1為每一行呼叫一個函式:
subset = df[df.apply(lambda x: x['Name'].lower() in x['Fname'].lower(), axis=1)]
輸出:
>>> subset
Name Age Fname
1 Bob 12 Bob
2 Clarke 13 clarke
uj5u.com熱心網友回復:
通過串列理解的其他選項是否適合您:
df.loc[[left.lower() in right.lower()
for left, right
in zip(df.Name, df.Fname)]
]
Name Age Fname
1 Bob 12 Bob
2 Clarke 13 clarke
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/373404.html
上一篇:如何找到確切的字串
