代码之家  ›  专栏  ›  技术社区  ›  IRSAgent

在SQL联接中使用熊猫数据帧

  •  0
  • IRSAgent  · 技术社区  · 6 年前

    我正试图使用Postgres数据库中的外部表对数据帧的内容执行SQL联接。

    这就是数据帧的外观:

    >>> df
       name  author  count
    0  a     b       10
    1  c     d       5
    2  e     f       2
    

    我需要将它与如下所示的Postgres表连接:

    TABLE: blog
    title   author    url    
    a       b         w.com
    b       b         x.com
    e       g         y.com
    

    这是我要做的,但这似乎不是查询的正确语法:

    >>> sql_join = r"""select b.*, frame.*  from ({0}) frame
            join blog b
            on frame.name = b.title
            where frame.owner = b.owner 
            order by frame.count desc
            limit 30;""".format(df)
    
    >>> res = pd.read_sql(sql_join, connection)
    

    我不确定如何在SQL查询中使用数据帧中的值。 有人能给我指个方向吗?谢谢!

    编辑 :根据我的用例,我无法将blog表转换为给定内存和性能约束的数据帧。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Mayank Porwal    6 年前

    您应该从postgres表中创建另一个数据帧,然后连接这两个数据帧。

    你可以使用 read_sql 要从表创建df,请执行以下操作:

    import psycopg2  ## Python connector library to Postgres
    import pandas as pd
    
    conn = psycopg2.connect(...) ## Put your DB credentials here
    blog_df = pd.read_sql('blog', con=conn)
    ## This will bring `blog` table's data into blog_df
    

    它应该是这样的:

    In [258]: blog_df
    Out[258]: 
      title author    url
    0     a      b  w.com
    1     b      b  x.com
    2     e      g  y.com
    

    现在,你可以加入 df blog_df 使用 merge 如下所示:

    In [261]: pd.merge(df, blog_df, left_on='name', right_on='title')
    Out[261]: 
      name author_x  count title author_y    url
    0    a        b     10     a        b  w.com
    1    e        f      2     e        g  y.com
    

    你会得到上面这样的结果。你可以进一步清理。

    如果有帮助,请告诉我。

        2
  •  0
  •   IRSAgent    6 年前

    我成功地做到了这一点,不需要将数据帧转换为临时表,也不需要将SQL从blog表中读取为数据帧。

    对于其他面临同样问题的人,这是通过使用一个虚拟的排序表来实现的。

    这就是我最后一个SQL查询的样子:

    >>> inner_string = "VALUES ('a','b',10), ('c','d',5), ('e','f',2)"
    
    >>> sql_join = r"""SELECT * FROM blog
            JOIN ({0}) AS frame(title, owner, count)
            ON blog.title = frame.title
            WHERE blog.owner = frame.owner 
            ORDER BY frame.count DESC
            LIMIT 30;""".format(inner_string)
    
    >>> res = pd.read_sql(sql_join, connection)
    

    可以使用字符串操作将数据帧中的所有行转换为一个类似于 inner_string .