在多列中查找字符串?

时间:2014-11-17 10:39:17

标签: pandas

我有一个包含3列tel1,tel2,tel3的数据帧 我想在一列或多列中保留包含特定值的行:

例如,我想保留列tel1或tel2或tel3以'06'开头的行

我该怎么做? 感谢

2 个答案:

答案 0 :(得分:6)

让我们使用此df作为示例DataFrame:

In [54]: df = pd.DataFrame({'tel{}'.format(j): 
                            ['{:02d}'.format(i+j) 
                             for i in range(10)] for j in range(3)})

In [71]: df
Out[71]: 
  tel0 tel1 tel2
0   00   01   02
1   01   02   03
2   02   03   04
3   03   04   05
4   04   05   06
5   05   06   07
6   06   07   08
7   07   08   09
8   08   09   10
9   09   10   11

您可以使用df['tel0']找到'06'中的哪些值 StringMethods.startswith

In [72]: df['tel0'].str.startswith('06')
Out[72]: 
0    False
1    False
2    False
3    False
4    False
5    False
6     True
7    False
8    False
9    False
Name: tel0, dtype: bool

要将两个布尔系列与逻辑或组合使用,请使用|

In [73]: df['tel0'].str.startswith('06') | df['tel1'].str.startswith('06')
Out[73]: 
0    False
1    False
2    False
3    False
4    False
5     True
6     True
7    False
8    False
9    False
dtype: bool

或者,如果你想使用logical-or组合一个布尔系列列表,你可以使用reduce

In [79]: import functools
In [80]: import numpy as np
In [80]: mask = functools.reduce(np.logical_or, [df['tel{}'.format(i)].str.startswith('06') for i in range(3)])

In [81]: mask
Out[81]: 
0    False
1    False
2    False
3    False
4     True
5     True
6     True
7    False
8    False
9    False
Name: tel0, dtype: bool

获得布尔值mask后,您可以使用df.loc选择关联的行:

In [75]: df.loc[mask]
Out[75]: 
  tel0 tel1 tel2
4   04   05   06
5   05   06   07
6   06   07   08

注意除了startwith之外还有许多其他vectorized str methods。 您可能会发现str.contains对于查找包含字符串的行非常有用。请注意,str.contains默认将其参数解释为正则表达式模式:

In [85]: df['tel0'].str.contains(r'6|7')
Out[85]: 
0    False
1    False
2    False
3    False
4    False
5    False
6     True
7     True
8    False
9    False
Name: tel0, dtype: bool

答案 1 :(得分:1)

我喜欢在这种情况下使用dataframe.apply:


    #search dataframe multip columns

#generate some random numbers
import random as r
rand_numbers = [[r.randint(100000, 9999999) for __ in range(3)] for _ in range(20)]
df = pd.DataFrame.from_records(rand_numbers, columns=['tel1','tel2','tel3'])

df.head()

#a really simple search function
#if you need speed use cpython here ;-)
def searchfilter(row, search='5'):
    #df.apply returns the rows or columns as list
    for string in row:
        #string is a number here, so we must cast it.
        if str(string).startswith(search):
            return True
        else:
            return False

#apply the searchfunction to each row    
result_bool_array =df.apply(searchfilter, axis=1) #the axis argument is to run it rowise

df[result_bool_array]
#other search with lambda in apply
result_bool_array =df.apply(lambda row: searchfilter(row, search='6'), axis=1)