zoukankan      html  css  js  c++  java
  • SQL 查询的 15 个 Pandas 函数

    Import data from SQL to Python

    In [1]:
    # Let's start with connecting SQL with Python and Importing the SQL data as DataFrame
    import pyodbc
    import pandas as pd
    import numpy as np
    connection_string = ("Driver={SQL Server Native Client 11.0};"
                "Server=Your_Server_Name;"
                "Database=My_Database_Name;"
                "UID=Your_User_ID;"
                "PWD=Your_Password;")
    connection = pyodbc.connect(connection_string)
    # Using the same query as above to get the output in dataframe
    # We are importing top 10 rows and all the columns of State_Population Table
    population = pd.read_sql('SELECT TOP(10) * FROM State_Population', connection)
    # OR
    # write the query and assign it to variable
    query = 'SELECT * FROM STATE_AREAS WHERE [area (sq. mi)] > 100000'
    # use the variable name in place of query string
    area = pd.read_sql(query, connection)
     
    The output above is imported in Python as Pandas DataFrame.

    Once we have the data in the form of DataFrame, now we can see how to manipulate them using Pandas in Python. In this article, we are going to see how we can replicate the SQL constructs in Python. There is no one “Best” way, but many good paths. You chose the one you wish for.

     

    Basic SQL Queries

    We are going to deconstruct the most basic of the SQL queries and see how the same result can be achieved in Python. The queries which we will discuss in this article are

    • SELECT column_name(s)
    • FROM table_name
    • WHERE condition
    • GROUP BY column_name(s)
    • HAVING condition
    • ORDER BY column_name(s)

    The methodology we are going to adopt is like this: We will write a SQL query, and then list some possible ways in which the same result can be achieved in Python. We have three tables in the database which we are going to use, and we have imported two of them as DataFrames in Python already. We will use one of these Data Frames (population) to understand these concepts.

    The table State_Population is already imported and the DataFrame is named as population.

    In [2]:

    population.head()

    Out[2]:

     state/regionagesyearpopulation
    0 AL under18 2012 1117489.0
    1 AL total 2012 4817528.0
    2 AL under18 2010 1130966.0
    3 AL total 2010 4785570.0
    4 AL under18 2011 1125763.0
     

    Let us see how to replicate the SQL function in Python and get the same or similar results.

    Note: The main headings are the broad SQL query names. And inside those headings, the actual SQL query being used to replicate are written in BOLD and note format. Below them, all the Python ways to replicate them are mentioned as numbered methods, one after the other.

    SELECT column_name(s)

    FROM table_name

    SELECT * FROM State_Population;

    This SQL query will fetch all the columns (and all the rows too) from the state_population table. The same result can be achieved by simply calling the DataFrame in Python.

    1.  Call the DataFrame in Python

    In [3]:
     
    population
     
    Out[3]:
     state/regionagesyearpopulation
    0 AL under18 2012 1117489.0
    1 AL total 2012 4817528.0
    2 AL under18 2010 1130966.0
    3 AL total 2010 4785570.0
    4 AL under18 2011 1125763.0
    2539 USA total 2010 309326295.0
    2540 USA under18 2011 73902222.0
    2541 USA total 2011 311582564.0
    2542 USA under18 2012 73708179.0
    2543 USA total 2012 313873685.0

    2544 rows × 4 columns

     

    SELECT year FROM State_Population;

    此 SQL 查询将从 state_population 表中获取列(年)和所有行。在Python中,可以通过以下方式实现。这里要注意的一件事是,当我们只选择一列时,它会从 Pandas DataFrame 对象转换为 Pandas 系列对象。我们使用 DataFrame 函数将其转换回 DataFrame。

     

    2.  Call the DataFrame.ColumnName

    In [4]:
    # By calling the dataframe.column
    pd.DataFrame(population.year)

    SELECT population, year FROM State_Population;

    This query will fetch two columns(population and year) and all the rows from the state_population table. In Python, it can be achieved in the following ways.

    3.  Call the DataFrame with column names (Selecting)

    Notice the names of the columns as a list, inside the indexing brackets [].

    In [5]:
    population[['population', 'year']]

    4.  Use the pandas .loc() method

    The syntax for loc method is df.loc([row names], [column names]). If instead of the list of names, only “:” is passed, it means to consider all. So df.loc(: , [column names]) means fetch all rows for the given column names.

     
    loc 方法的语法是df.loc([row names], [column names])如果只传递“ :”而不是名称列表,则表示考虑所有。所以df.loc(: , [column names])意味着获取给定列名的所有行
     
    In [6]:
    population.loc[:,['population', 'year']] 

    The DataFrame above is the output from all the above codes. Different methods, same output.

     

    SELECT column_name(s)

    FROM table_name

    WHERE condition

    SELECT * FROM State_Population WHERE year = 2010;

    This query will fetch all the columns and only those rows from the state_population table where the year column has a value equal to 2010. In Python, it can be achieved in the following ways.

    5.  Use Python’s Slicing method

    In [7]:
    population[population.year == 2010]

    6.  Use pandas .loc() method

    In [8]:

    population.loc[population.year == 2010,:]

    7.  Use pandas .query() method

    Notice that the input for df.query() is always a string.

    In [9]:
    population.query('year == 2010')

    8.使用pandas lambda函数

    请注意,使用了 apply 方法, lambda 函数应用于列的每个元素。然后将其结果送入索引括号内以对原始 DataFrame 进行切片。

    In [10]:
    population[population.apply(lambda x: x["year"] == 2010, axis=1)]

    Out[10]:

     state/regionagesyearpopulation
    2 AL under18 2010 1130966.0
    3 AL total 2010 4785570.0
    90 AK under18 2010 187902.0
    91 AK total 2010 713868.0
    100 AZ under18 2010 1628563.0
    2405 WY total 2010 564222.0
    2490 PR total 2010 3721208.0
    2491 PR under18 2010 896945.0
    2538 USA under18 2010 74119556.0
    2539 USA total 2010 309326295.0

    106 rows × 4 columns

     

    The DataFrame above is the output from all the above codes. Different methods, same output.

     

    SELECT state/region, population, year FROM State_Population WHERE year = 2010 or 2012 and ages = under18;

    此查询将获取这三列(州/地区、人口、年份)以及 state_population 表中年份列的值等于 2010 或 2012 且年龄列的值等于“under18”的那些行。在Python中,可以通过以下方式实现。

     

    9.  Use Pythons indexing and slicing

    In [11]:
    # By using Pythons indexing and slicing
    population[(population.year.isin([2010, 2012])) & (population.ages == "under18")][['state/region', 'population', 'year']]

    Out[11]:

     state/regionpopulationyear
    0 AL 1117489.0 2012
    2 AL 1130966.0 2010
    90 AK 187902.0 2010
    94 AK 188162.0 2012
    96 AZ 1617149.0 2012
    2404 WY 135351.0 2010
    2491 PR 896945.0 2010
    2494 PR 841740.0 2012
    2538 USA 74119556.0 2010
    2542 USA 73708179.0 2012

    106 rows × 3 columns

     

    10.  Use pandas .loc() method

    In [12]:
    population.query('(year==2010 | year==2012) & ages == "under18"')[['state/region', 'population', 'year']]

    Out[12]:

     state/regionpopulationyear
    0 AL 1117489.0 2012
    2 AL 1130966.0 2010
    90 AK 187902.0 2010
    94 AK 188162.0 2012
    96 AZ 1617149.0 2012
    2404 WY 135351.0 2010
    2491 PR 896945.0 2010
    2494 PR 841740.0 2012
    2538 USA 74119556.0 2010
    2542 USA 73708179.0 2012

    106 rows × 3 columns

     

    11.  Use pandas .query() method

    Notice that the input for df.query() is always a string.

    In [13]:
    population.query('(year==2010 | year==2012) & ages == "under18"')[['state/region', 'population', 'year']]

    Out[13]:

     state/regionpopulationyear
    0 AL 1117489.0 2012
    2 AL 1130966.0 2010
    90 AK 187902.0 2010
    94 AK 188162.0 2012
    96 AZ 1617149.0 2012
    2404 WY 135351.0 2010
    2491 PR 896945.0 2010
    2494 PR 841740.0 2012
    2538 USA 74119556.0 2010
    2542 USA 73708179.0 2012

    106 rows × 3 columns

     

    12.  Use lambda function

    In [14]:
    population[population.apply(lambda x: (x["year"] in [2010, 2012]) & (x["ages"] == "under18"), axis=1)]

    Out[14]:

     state/regionagesyearpopulation
    0 AL under18 2012 1117489.0
    2 AL under18 2010 1130966.0
    90 AK under18 2010 187902.0
    94 AK under18 2012 188162.0
    96 AZ under18 2012 1617149.0
    2404 WY under18 2010 135351.0
    2491 PR under18 2010 896945.0
    2494 PR under18 2012 841740.0
    2538 USA under18 2010 74119556.0
    2542 USA under18 2012 73708179.0

    106 rows × 4 columns

     

    The DataFrame above is the output from all the above codes. Different methods, same output.

     

    SELECT column_name(s)

    FROM table_name

    WHERE condition

    GROUP BY column_name(s)

    HAVING condition

    SELECT * FROM State_Population WHERE ages = total GROUP BY state/region HAVING AVG(population) > 10000000;

    SQL 和 Pandas 的 Group By 功能从表面上看是一样的,但 Pandas groupby 的能力和效率要高得多,尤其是对于更复杂的操作。为了在python中从SQL中实现上述操作,让我们近距离看看pandas groupby函数。

    可以使用一列或多列进行分组。对于一列,只需传递列名,对于多列,将名称作为列表传递。
     
    In [15]:
    # grouped by state/region
    population.groupby(by = 'state/region')

    Out[15]:

    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000016982CD0408>
    In [16]:
    # grouped by state/region and year
    population.groupby(by = ['state/region', 'year'])
     
    Out[16]:
    <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000016982D7A908>
     

    输出是一个 groupby 对象。输出显示分组已经完成,并且 groupby 函数完成了它的工作。但是由于我们没有被告知按哪个函数聚合,因此输出不是 DataFrame 的形式。所以让我们现在就这样做。

     

     
    In [17]:
    population.groupby(by = ['state/region', 'year']).count()

    Out[17]:

      agespopulation
    state/regionyear  
    AK1990 2 2
    1991 2 2
    1992 2 2
    1993 2 2
    1994 2 2
    WY2009 2 2
    2010 2 2
    2011 2 2
    2012 2 2
    2013 2 2

    1272 rows × 2 columns

     

    我们可以将这个 groupby 对象分配给一个变量,然后使用该变量进行进一步的操作。

    In [18]:
    grouped = population.groupby(by = ['state/region', 'year'])
     

    现在让我们复制 SQL 查询。要添加 HAVING 函数,我们需要使用 groupby 然后过滤条件。上述SQL代码的python实现如下。

    13.  groupby and aggregate in Pandas

    In [19]:
    df = pd.DataFrame(population.loc[population.ages == 'total', :].groupby(by = 'state/region').aggregate('population').mean())
    ​df.loc[df.population > 10000000, :] 
     
    Out[19]:
     population
    state/region 
    CA 3.433414e+07
    FL 1.649654e+07
    IL 1.237080e+07
    NY 1.892581e+07
    OH 1.134238e+07
    PA 1.236960e+07
    TX 2.160626e+07
    USA 2.849979e+08
     

    SELECT column_name(s)

    FROM table_name

    WHERE condition

    GROUP BY column_name(s)

    HAVING condition

    ORDER BY column_name(s)

    SELECT * FROM State_Population WHERE ages = total GROUP BY state/region HAVING AVG(population) > 10000000 ORDER BY population;

    The order by in SQL is used to sort the table in the given order. In the above SQL code, the table needs to be ordered in ascending order (default). This task can be accomplished by using the pandas sort_values() method.

    14.  Order by using sort_values() in Python

    In [20]:
    df = pd.DataFrame(population.loc[population.ages == 'total', :].groupby(by = 'state/region').aggregate('population').mean())
     df.loc[df .population > 10000000, :].sort_values(by = 'population')
     
    Out[20]:
     population
    state/region 
    OH 1.134238e+07
    PA 1.236960e+07
    IL 1.237080e+07
    FL 1.649654e+07
    NY 1.892581e+07
    TX 2.160626e+07
    CA 3.433414e+07
    USA 2.849979e+08
     

    默认情况下按升序进行排序。要改变这一点,应使用升序 = False

    In [21]:
    df.loc[df.population > 10000000, :].sort_values(by = 'population', ascending = False)

    Out[21]:

     population
    state/region 
    USA 2.849979e+08
    CA 3.433414e+07
    TX 2.160626e+07
    NY 1.892581e+07
    FL 1.649654e+07
    IL 1.237080e+07
    PA 1.236960e+07
    OH 1.134238e+07
     

     

    Bonus: 

    按多列排序

    Pandas 提供了按多列排序的功能。不仅如此,您还可以选择哪些列按升序排序,哪些列按降序排序。让我们对我们的人口数据集进行分组和排序。我们将根据州和年份对它们进行分组,然后根据年份和人口对它们进行排序。

    15. sort_values() 在不止一列上

    In [22]:
    # Grouping by and the grouped table
    grouped = population.groupby(by = ['state/region', 'year']).mean()
    grouped
     
     
    Out[22]:
      population
    state/regionyear 
    AK1990 365396.0
    1991 376186.5
    1992 386807.0
    1993 393312.0
    1994 395373.5
    WY2009 347405.5
    2010 349786.5
    2011 351368.0
    2012 356576.0
    2013 360168.5

    1272 rows × 1 columns

    In [23]:
    # Sorting the Grouped table in 
    # Ascending order of Year and (Increasing Year)
    # Descending order of population (decreasing population)
    grouped.sort_values(by = ['year', 'population'], ascending=[True, False])
     
     
    Out[23]:
      population
    state/regionyear 
    USA1990 156920663.0
    CA1990 18970008.0
    NY1990 11151213.5
    TX1990 10981487.5
    FL1990 8011057.0
    AK2013 461632.0
    ND2013 443040.5
    DC2013 378961.5
    VT2013 374665.5
    WY2013 360168.5

    1272 rows × 1 columns

     

    6 结论:

    您一定想知道组织如何管理其庞大的数据库。他们肯定不会将其保存在 Excel 或其他电子表格格式中。现实生活中的业务数据库维护在关系数据库系统中,该系统最常使用 SQL 创建和访问。因此,了解 SQL 是任何数据科学家的必备工具。但 SQL 不仅仅是一个数据挑选工具,功能更强大。它能够完成许多数据整理和数据操作任务。但 Python 也是如此。

    现在没有一种语言足以完成所有的任务,具有操作效率。因此,对 SQL 和 Python 的深入理解将帮助您选择使用哪一个来完成哪个任务。

    如果您只想对数据进行选择、筛选和基本操作,则可以在 SQL 中高效地完成。但是如果需要复杂的分组操作和更多的数据操作,Python 中的 Pandas 将是一个更合适的选择。

    使用多种数据分析语言有很多好处,因为您可以自定义和使用非常适合您不断变化的需求的混合方法。

     

  • 相关阅读:
    rabbitmq
    C#操作redis
    C#设计模式——桥接模式
    C#设计模式——代理模式
    C#设计模式——外观者模式
    WPF Item内TextBox获取焦点时如何选中当前Item
    解决异常System.Runtime.Interopservices.COMException RequestLock问题
    【转】WPF中Binding的技巧(一)
    【转】WPF中的Binding技巧(二)
    ASP.NET State Service服务
  • 原文地址:https://www.cnblogs.com/a00ium/p/15548931.html
Copyright © 2011-2022 走看看