首页 > 解决方案 > 检查DataFrame中的第n个值是否等于字符串中的第n个字符

问题描述

我有一个df:

df =
     c1  c2   c3   c4  c5
  0  K   6    nan  Y   V
  1  H   nan  g    5   nan
  2  U   B    g    Y   L

还有一根弦

s = 'HKg5'

我想返回 s[0]=c1 的值,s[1]=c2 的值,..... + 在某些情况下 s[i]=nan 的行。

例如,上面 df 中的第 1 行与字符串匹配

    row 1=
           c1  c2   c3   c4  c5
        1  H   nan  g    5   nan
                                                match=True,   regardless of s[1,4]=nan
     s   = H   K    g    5

而且字符串长度是动态的,所以我的 df cols 高于 c10

我正在使用 df.apply 但我无法清楚地弄清楚。我想写一个函数传递给df.apply,同时传递字符串。

谢谢你的帮助!

克里斯回答的输出

  df=  
        c1  c2  c3  c4  c5 
     0  K   6  NaN  Y   V
     1  H  NaN  g   5  NaN
     2  U   B   g   Y   L

  s = 'HKg5'
  s1 = pd.Series(list(s), index=[f'c{x+1}' for x in range(len(s))])
  df.loc[((df == s1) | (df.isna())).all(1)]

输出

  `c1  c2  c3  c4  c5`

标签: pythonpandasnumpydata-structuresdata-science

解决方案


从您的字符串创建一个助手Series并使用布尔逻辑进行过滤:

s1 = pd.Series(list(s), index=[f'c{x+1}' for x in range(len(s))])

# print(s1)    
# c1    H
# c2    K
# c3    g
# c4    5
# dtype: object

逻辑df等于 ( ==) 此值OR ( |) 是 nan ( isna)沿轴 1
使用all返回所有值都为True

df.loc[((df == s1) | (df.isna())).all(1)]

[出去]

  c1   c2 c3 c4   c5
1  H  NaN  g  5  NaN

所以,作为一个函数,你可以这样做:

def df_match_string(frame, string):
    s1 = pd.Series(list(string), index=[f'c{x+1}' for x in range(len(string))])
    return ((frame == s1) | (frame.isna())).all(1)

df_match_string(df, s)

[出去]

0    False
1     True
2    False
dtype: bool

更新

我无法使用提供的示例重现您的问题。我的猜测是您的 DataFrame 中的某些值可能有前导/尾随空格?

在尝试上述解决方案之前,请尝试以下预处理步骤:

for col in df:
    df[col] = df[col].str.strip()

推荐阅读