Python 如果列中的值在一组值列表中,则筛选数据帧行

Python 如果列中的值在一组值列表中,则筛选数据帧行,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个Python数据帧rpt: rpt <class 'pandas.core.frame.DataFrame'> MultiIndex: 47518 entries, ('000002', '20120331') to ('603366', '20091231') Data columns: STK_ID 47518 non-null values STK_Name 47518 non-null val

我有一个Python数据帧
rpt

rpt
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 47518 entries, ('000002', '20120331') to ('603366', '20091231')
Data columns:
STK_ID                    47518  non-null values
STK_Name                  47518  non-null values
RPT_Date                  47518  non-null values
sales                     47518  non-null values
我想把一些股票的所有行放在一起,比如
['600809','600141','600329']
。这意味着我需要这样的语法:

stk_list = ['600809','600141','600329']

rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas 

既然熊猫不接受上述命令,如何实现目标

使用
isin
方法:


rpt[rpt['STK_ID'].isin(STK_列表)]
使用
isin
方法:


rpt[rpt['STK_ID'].isin(STK_列表)]

您还可以通过以下方式使用范围:

b = df[(df['a'] > 1) & (df['a'] < 5)]
b=df[(df['a']>1)和(df['a']<5)]

您还可以通过以下方式使用范围:

b = df[(df['a'] > 1) & (df['a'] < 5)]
b=df[(df['a']>1)和(df['a']<5)]
isin()
如果您有精确匹配的列表,则是理想的选择,但是如果您有要查找的部分匹配或子字符串列表,则可以使用方法和正则表达式进行筛选

例如,如果我们想要返回一个数据帧,其中所有股票ID以
'600'
开头,然后后跟任意三位数字:

>>> rpt[rpt['STK_ID'].str.contains(r'^600[0-9]{3}$')] # ^ means start of string
...   STK_ID   ...                                    # [0-9]{3} means any three digits
...  '600809'  ...                                    # $ means end of string
...  '600141'  ...
...  '600329'  ...
...      ...   ...
假设现在我们有一个字符串列表,我们希望
'STK_ID'
中的值以其结尾,例如

endstrings = ['01$', '02$', '05$']
我们可以将这些字符串与regex'或'character
|
连接起来,并将字符串传递给
str.contains
以过滤数据帧:

>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
...   STK_ID   ...
...  '155905'  ...
...  '633101'  ...
...  '210302'  ...
...      ...   ...
最后,
contains
可以忽略大小写(通过设置
case=False
),允许您在指定要匹配的字符串时更加通用

比如说,

str.contains('pandas', case=False)
将匹配
PANDAS
PANDAS
paNdAs123
,等等。

isin()
如果您有精确匹配的列表,则非常理想,但如果您有要查找的部分匹配或子字符串列表,则可以使用该方法和正则表达式进行筛选

例如,如果我们想要返回一个数据帧,其中所有股票ID以
'600'
开头,然后后跟任意三位数字:

>>> rpt[rpt['STK_ID'].str.contains(r'^600[0-9]{3}$')] # ^ means start of string
...   STK_ID   ...                                    # [0-9]{3} means any three digits
...  '600809'  ...                                    # $ means end of string
...  '600141'  ...
...  '600329'  ...
...      ...   ...
假设现在我们有一个字符串列表,我们希望
'STK_ID'
中的值以其结尾,例如

endstrings = ['01$', '02$', '05$']
我们可以将这些字符串与regex'或'character
|
连接起来,并将字符串传递给
str.contains
以过滤数据帧:

>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
...   STK_ID   ...
...  '155905'  ...
...  '633101'  ...
...  '210302'  ...
...      ...   ...
最后,
contains
可以忽略大小写(通过设置
case=False
),允许您在指定要匹配的字符串时更加通用

比如说,

str.contains('pandas', case=False)
将匹配
PANDAS
PANDAS
paNdAs123
,等等。

您也可以直接使用数据帧获取此信息

rpt.query('STK_ID in (600809,600141,600329)')
或类似地搜索范围:

rpt.query('60000 < STK_ID < 70000')
rpt.query('60000
您也可以直接从数据帧获取此信息

rpt.query('STK_ID in (600809,600141,600329)')
或类似地搜索范围:

rpt.query('60000 < STK_ID < 70000')
rpt.query('60000
您可以使用
查询
,即:

b = df.query('a > 1 & a < 5')
b=df.query('a>1&a<5')

您可以使用
查询
,即:

b = df.query('a > 1 & a < 5')
b=df.query('a>1&a<5')
使用熊猫切片数据 给定这样的数据帧:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4
mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4
有多种选择或切片数据的方法

使用.isin 最明显的是
.isin
功能。您可以创建一个掩码,为您提供一系列
True
/
False
语句,这些语句可应用于以下数据帧:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4
mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4
掩蔽是问题的临时解决方案,但在速度和内存方面并不总是表现良好

带索引 通过将索引设置为
STK_ID
列,我们可以使用pandas内置的切片对象
.loc

df.set_index('STK_ID', inplace=True)
         RPT_Date STK_Name  sales
STK_ID                           
0      1980-01-01   Arthur      0
1      1980-01-02    Beate      4
2      1980-01-03    Cecil      2
3      1980-01-04     Dana      8
4      1980-01-05     Eric      4
5      1980-01-06    Fidel      5
6      1980-01-07   George      4
7      1980-01-08     Hans      7
8      1980-01-09   Ingrid      7
9      1980-01-10    Jones      4

df.loc[[4, 2, 6]]
         RPT_Date STK_Name  sales
STK_ID                           
4      1980-01-05     Eric      4
2      1980-01-03    Cecil      2
6      1980-01-07   George      4
这是一种快速的方法,即使索引可能需要一点时间,但如果您想执行这样的多个查询,也可以节省时间

合并数据帧 这也可以通过合并数据帧来实现。这更适合于比这些示例中的数据多得多的场景

stkid_df = pd.DataFrame({"STK_ID": [4,2,6]})
df.merge(stkid_df, on='STK_ID')
   STK_ID   RPT_Date STK_Name  sales
0       2 1980-01-03    Cecil      2
1       4 1980-01-05     Eric      4
2       6 1980-01-07   George      4
注 即使有多行具有相同的
'STK_ID'

使用pandas切片数据,上述所有方法也可以工作 给定这样的数据帧:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4
mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4
有多种选择或切片数据的方法

使用.isin 最明显的是
.isin
功能。您可以创建一个掩码,为您提供一系列
True
/
False
语句,这些语句可应用于以下数据帧:

    RPT_Date  STK_ID STK_Name  sales
0 1980-01-01       0   Arthur      0
1 1980-01-02       1    Beate      4
2 1980-01-03       2    Cecil      2
3 1980-01-04       3     Dana      8
4 1980-01-05       4     Eric      4
5 1980-01-06       5    Fidel      5
6 1980-01-07       6   George      4
7 1980-01-08       7     Hans      7
8 1980-01-09       8   Ingrid      7
9 1980-01-10       9    Jones      4
mask = df['STK_ID'].isin([4, 2, 6])

mask
0    False
1    False
2     True
3    False
4     True
5    False
6     True
7    False
8    False
9    False
Name: STK_ID, dtype: bool

df[mask]
    RPT_Date  STK_ID STK_Name  sales
2 1980-01-03       2    Cecil      2
4 1980-01-05       4     Eric      4
6 1980-01-07       6   George      4
掩蔽是问题的临时解决方案,但在速度和内存方面并不总是表现良好

带索引 通过将索引设置为
STK_ID
列,我们可以使用pandas内置的切片对象
.loc

df.set_index('STK_ID', inplace=True)
         RPT_Date STK_Name  sales
STK_ID                           
0      1980-01-01   Arthur      0
1      1980-01-02    Beate      4
2      1980-01-03    Cecil      2
3      1980-01-04     Dana      8
4      1980-01-05     Eric      4
5      1980-01-06    Fidel      5
6      1980-01-07   George      4
7      1980-01-08     Hans      7
8      1980-01-09   Ingrid      7
9      1980-01-10    Jones      4

df.loc[[4, 2, 6]]
         RPT_Date STK_Name  sales
STK_ID                           
4      1980-01-05     Eric      4
2      1980-01-03    Cecil      2
6      1980-01-07   George      4
这是一种快速的方法,即使索引可能需要一点时间,但如果您想执行这样的多个查询,也可以节省时间

合并数据帧 这也可以通过合并数据帧来实现。这更适合于比这些示例中的数据多得多的场景

stkid_df = pd.DataFrame({"STK_ID": [4,2,6]})
df.merge(stkid_df, on='STK_ID')
   STK_ID   RPT_Date STK_Name  sales
0       2 1980-01-03    Cecil      2
1       4 1980-01-05     Eric      4
2       6 1980-01-07   George      4

即使有多行具有相同的“STK\U ID”

您也可以通过使用“查询”和@获得类似的结果,上述所有方法都有效:

例如:


您还可以使用“查询”和@获得类似的结果:

例如:


对这一点的否定是什么呢?<代码>的正确方式是什么!isin()?@dbyte:您只需使用
~
运算符:
rpt[~rpt['STK_ID'].isin(STK_list)]
与@mathtick询问的内容相关:是否有一种方法可以对索引(不一定是多索引)执行此操作@user1669710:索引也有一个
isin
方法。如果有人需要索引的语法:
df[df.index.isin(ls)]
在哪里ls是你的列表呢?对它的否定是什么呢?
!isin()
?@dbyte:你只需要使用
~
操作符:
rpt[~rpt['STK\u ID'].isin(STK\u list)]
与@mathdick问的问题相关:一般来说,有什么方法可以在索引上这样做吗(不一定