big*_*bug 378 python dataframe pandas
我有一个Python pandas DataFrame 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
Run Code Online (Sandbox Code Playgroud)
我可以过滤库存ID '600809'如下的行:rpt[rpt['STK_ID'] == '600809']
<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
Run Code Online (Sandbox Code Playgroud)
我想把一些股票的所有行放在一起,例如['600809','600141','600329'].这意味着我想要这样的语法:
stk_list = ['600809','600141','600329']
rst = rpt[rpt['STK_ID'] in stk_list] # this does not works in pandas
Run Code Online (Sandbox Code Playgroud)
由于大熊猫不接受上述命令,如何实现目标?
Bre*_*arn 562
使用该isin方法. rpt[rpt['STK_ID'].isin(stk_list)].
Ale*_*ley 106
isin()如果你有一个完全匹配的列表是理想的,但如果你有一个要查找的部分匹配或子串的列表,你可以使用str.contains方法和正则表达式进行过滤.
例如,如果我们想要返回一个DataFrame,其中所有以#开头的库存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' ...
... ... ...
Run Code Online (Sandbox Code Playgroud)
假设现在我们有一个字符串列表,我们希望这些字符串'STK_ID'结束,例如
endstrings = ['01$', '02$', '05$']
Run Code Online (Sandbox Code Playgroud)
我们可以使用正则表达式'或'字符连接这些字符串,|并传递字符串str.contains以过滤DataFrame:
>>> rpt[rpt['STK_ID'].str.contains('|'.join(endstrings)]
... STK_ID ...
... '155905' ...
... '633101' ...
... '210302' ...
... ... ...
Run Code Online (Sandbox Code Playgroud)
最后,contains可以忽略大小写(通过设置case=False),允许您在指定要匹配的字符串时更通用.
例如,
str.contains('pandas', case=False)
Run Code Online (Sandbox Code Playgroud)
将匹配PANDAS,PanDAs,paNdAs123,等等.
yem*_*emu 42
您还可以使用以下范围来使用范围:
b = df[(df['a'] > 1) & (df['a'] < 5)]
Run Code Online (Sandbox Code Playgroud)
bsc*_*can 38
您还可以直接在DataFrame中查询此信息.
rpt.query('STK_ID in (600809,600141,600329)')
Run Code Online (Sandbox Code Playgroud)
或者类似地搜索范围:
rpt.query('60000 < STK_ID < 70000')
Run Code Online (Sandbox Code Playgroud)
fir*_*ynx 23
给定这样的数据帧:
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
Run Code Online (Sandbox Code Playgroud)
有多种方法可以选择或切片数据.
最明显的是该.isin功能.您可以创建一个掩码,为您提供一系列True/ False语句,这些语句可以应用于这样的数据帧:
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
Run Code Online (Sandbox Code Playgroud)
屏蔽是问题的临时解决方案,但在速度和内存方面并不总是表现良好.
通过将索引设置为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
Run Code Online (Sandbox Code Playgroud)
这是快速执行此操作的方法,即使索引可能需要一段时间,如果您想要执行此类多个查询,也可以节省时间.
这也可以通过合并数据帧来完成.对于比这些示例中包含更多数据的情况,这更适合.
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
Run Code Online (Sandbox Code Playgroud)
即使有多行具有相同的行,上述所有方法也都有效 'STK_ID'
您还可以使用'query'和@来获得类似的结果:
例如:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
269363 次 |
| 最近记录: |