【问题标题】:Python Pandas - Find the elements ( substring ) in the same columnPython Pandas - 在同一列中查找元素(子字符串)
【发布时间】:2017-04-19 02:23:52
【问题描述】:

我有一个字符串列 ('b'),并希望在同一列中获取类似于子字符串的字符串。例如,在下面的数据框列 'b' 中,world 是 helloworld 的子字符串,ness 是 greatness 的子字符串。我想在列表中列出字符串 world 和 ness。能否请您提出解决方案。

     a           b
0  test       world
1  teat  helloworld
2   gor         bye
3   jhr   greatness
4   fre        ness

列表中的所需输出

listofsubstrings
Out[353]: ['world', 'ness']

【问题讨论】:

  • 你可以使用方法str.find(seach_str)。如果找到则返回 + 号,否则返回 -1
  • 我想你需要遍历 b 并检查每个值是否是 b 中另一个值的子字符串(使用类似 @anonyXmous 建议的东西)。顺便说一句,这可能需要一段时间,所以希望您的数据框不会太大

标签: python python-2.7 pandas dataframe


【解决方案1】:

你可以使用:

from itertools import product

#get unique values only
b = df.b.unique()
#create all combination
df1 = pd.DataFrame(list(product(b, b)), columns=['a', 'b'])
#filtering
df1 = df1[df1.apply(lambda x: x.a in x.b, axis=1) & (df1.a != df1.b)]
print (df1)
        a           b
1   world  helloworld
23   ness   greatness

print (df1.a.tolist())
['world', 'ness']

交叉连接的替代解决方案:

b = df.b.unique()
df['tmp'] = 1
df1 = pd.merge(df[['b','tmp']],df[['b','tmp']], on='tmp')
df1 = df1[df1.apply(lambda x: x.b_x in x.b_y, axis=1) & (df1.b_x != df1.b_y)]
print (df1)
      b_x  tmp         b_y
1   world    1  helloworld
23   ness    1   greatness

print (df1.b_x.tolist())
['world', 'ness']

【讨论】:

  • 如果我有 40,000 多行,这会有效吗?
  • 我认为没有,因为非常复杂的任务:(
  • 但最好还是试试吧。
【解决方案2】:

我们可以根据行索引是否是列标题的子字符串来创建一个真值数组。

l = df.b.dropna().values  # grab values from b
# double comprehension
a = np.array([[j in i for i in l] for j in l])
# of course strings are sub-strings of themselves
# lets ignore them by making the diagonal `False`
np.fill_diagonal(a, False)

# find the indices where the array is `True`
i, j = np.where(a)

l[i].tolist()

['world', 'ness']

更好的 imo

s = pd.Series(l[i], l[j])
s

helloworld    world
greatness      ness
dtype: object

【讨论】:

  • 当我执行 line 'a = np.array([[j in i for i in l] for j in l]) ' 我得到以下错误 'TypeError: argument of type 'NoneType'是不可迭代的'。如果有帮助,我会使用 pandas 0.12 版
  • @Joe_12345 那是因为您的列'b' 中有None。您应该将其包含在您的示例数据中,因为它是一个需要解决的问题。否则,您仍然会问这样的问题。但是,这样做应该可以解决它l = df.b.dropna().values
  • 很抱歉你是对的,这是我在重新创建要测试的 DataFrame 时不小心添加了 None 的错误。
【解决方案3】:

这可能对你有用:

df_cross = pd.DataFrame(data=np.asarray(df.b) + " " + df.b[:,None], columns=df.b)
df_indicator = df_cross.applymap(lambda x: x.split()[0] in x.split()[1])
df_indicator.sum(axis=0)[lambda x: x>1].index

Out[231]: Index([u'world', u'ness'], dtype='object')

【讨论】:

    猜你喜欢
    • 2018-03-14
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    相关资源
    最近更新 更多