Filter dataframe rows if value in column is in a set list of values
我有一个python pandas数据框
1 2 3 4 5 6 7 8 | 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 |
我可以这样过滤stock id为
1 2 3 4 5 6 7 | <class 'pandas.core.frame.DataFrame'> MultiIndex: 25 entries, ('600809', '20120331') to ('600809', '20060331') Data columns: STK_ID 25 non-null values STK_Name 25 non-null values RPT_Date 25 non-null values sales 25 non-null values |
我想把一些股票的所有行放在一起,如
1 2 3 | stk_list = ['600809','600141','600329'] rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas |
由于熊猫不接受上述命令,如何实现目标?
使用
如果您有精确匹配的列表,那么
例如,如果我们想要返回一个数据帧,其中所有以
1 2 3 4 5 6 | >>> 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' ... ... ... ... |
假设现在我们有一个字符串列表,希望
1 | endstrings = ['01$', '02$', '05$'] |
我们可以将这些字符串与regex'或'character
1 2 3 4 5 6 | >>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)] ... STK_ID ... ... '155905' ... ... '633101' ... ... '210302' ... ... ... ... |
最后,
例如,
1 | str.contains('pandas', case=False) |
与
您还可以使用范围:
1 | b = df[(df['a'] > 1) & (df['a'] < 5)] |
您还可以直接查询您的数据帧以获取此信息。
1 | rpt.query('STK_ID in (600809,600141,600329)') |
或类似地搜索范围:
1 | rpt.query('60000 < STK_ID < 70000') |
用熊猫切片数据
给定这样的数据帧:
1 2 3 4 5 6 7 8 9 10 11 | 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 |
选择或切片数据有多种方法。
使用ISIN最明显的是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
掩蔽是解决这个问题的特别方法,但在速度和内存方面并不总是表现得很好。
带索引通过设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
这是一种快速的方法,即使索引需要一段时间,如果您想执行这样的多个查询,也可以节省时间。
合并数据帧这也可以通过合并数据帧来实现。这将更适合您拥有比这些示例更多数据的场景。
1 2 3 4 5 6 | 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 |
注释
即使有多个行具有相同的
您还可以使用"query"和@来获得类似的结果:
如:
1 2 3 4 5 6 7 8 | df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']}) df = pd.DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]}) list_of_values = [3,6] result= df.query("A in @list_of_values") result A B 1 6 2 2 3 3 |
您可以使用
1 | b = df.query('a > 1 & a < 5') |