如何在Pandas中使用SQL查询风格选择数据子集?
介绍
在这篇文章中,我将向您展示如何使用Pandas进行SQL风格的过滤数据分析。大多数公司的数剧都存储在数据库中,需要使用SQL来检索和操作它。例如,Oracle、IBM、Microsoft等公司都有自己的数据库和SQL实现。
数据科学家在职业生涯的某个阶段必须处理SQL,因为数据并不总是存储在CSV文件中。我个人更喜欢使用Oracle,因为公司的大部分数据都存储在Oracle中。
场景一 假设我们有一个任务,需要从我们的电影数据集中找到满足以下条件的所有电影。
- 电影的语言必须是英语(en)或西班牙语(es)。
- 电影的受欢迎程度必须在500到1000之间。
- 电影的状态必须是已发行。
- 投票数必须大于5000。对于上述场景,SQL语句如下所示。
SELECT FROM WHERE title AS movie_title ,original_language AS movie_language ,popularityAS movie_popularity ,statusAS movie_status ,vote_count AS movie_vote_count movies_data original_languageIN ('en', 'es') AND status=('Released') AND popularitybetween 500 AND 1000 AND vote_count > 5000;
既然您已经看到了需求的SQL语句,让我们一步一步地使用pandas来实现它。我将向您展示两种方法。
方法一:布尔索引
1. 将movies_data数据集加载到DataFrame中。
import pandas as pd movies = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")
为每个条件分配一个变量。
languages = [ "en" , "es" ] condition_on_languages = movies . original_language . isin ( languages ) condition_on_status = movies . status == "Released" condition_on_popularity = movies . popularity . between ( 500 , 1000 ) condition_on_votecount = movies . vote_count > 5000
3. 将所有条件(布尔数组)组合在一起。
final_conditions = ( condition_on_languages & condition_on_status & condition_on_popularity & condition_on_votecount ) columns = [ "title" , "original_language" , "status" , "popularity" , "vote_count" ] # clubbing all together movies . loc [ final_conditions , columns ]
标题 | 原始语言 | 状态 | 受欢迎程度 | 投票数 |
---|---|---|---|---|
95 星际穿越 | en | 已发行 | 724.247784 | 10867 |
788 死侍 | en | 已发行 | 514.569956 | 10995 |
方法二:.query()方法。
.query()方法是SQL where子句风格的过滤数据的方式。条件可以作为字符串传递给此方法,但是列名不能包含任何空格。
如果列名中有空格,请使用python的replace函数将其替换为下划线。
根据我的经验,.query()方法应用于较大的DataFrame时,比之前的方法更快。
import pandas as pd movies = pd . read_csv ( "https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv" )
4. 构建查询字符串并执行方法。
请注意,.query方法不适用于跨多行的三引号字符串。
final_conditions = ( "original_language in ['en','es']" "and status == 'Released' " "and popularity > 500 " "and popularity < 1000" "and vote_count > 5000" ) final_result = movies . query ( final_conditions ) final_result
预算 | ID | 原始语言 | 原始标题 | 受欢迎程度 | 发行日期 | 收入 | 运行时间 | 状态 | |
---|---|---|---|---|---|---|---|---|---|
95 | 165000000 | 157336 | en | 星际穿越 | 724.247784 | 5/11/2014 | 675120017 | 169.0 | 已发行 |
788 | 58000000 | 293660 | en | 死侍 | 514.569956 | 9/02/2016 | 783112979 | 108.0 | 已发行 |
更多的情况是,在我的代码中,我有多个值需要在我的“in”子句中检查。所以上述语法并不适合这种场景。可以使用@符号引用Python变量。
您也可以以编程方式创建一个Python列表作为值,并与@一起使用。
movie_languages = [ 'en' , 'es' ] final_conditions = ( "original_language in @movie_languages " "and status == 'Released' " "and popularity > 500 " "and popularity < 1000" "and vote_count > 5000" ) final_result = movies . query ( final_conditions ) final_result
预算 | ID | 原始语言 | 原始标题 | 受欢迎程度 | 发行日期 | 收入 | 运行时间 | 状态 | |
---|---|---|---|---|---|---|---|---|---|
95 | 165000000 | 157336 | en | 星际穿越 | 724.247784 | 5/11/2014 | 675120017 | 169.0 | 已发行 |
788 | 58000000 | 293660 | en | 死侍 | 514.569956 | 9/02/2016 | 783112979 | 108.0 | 已发行 |
广告