如何将块中的数据从pandas数据帧加载到spark数据帧

时间:2016-07-30 23:37:19

标签: python pandas apache-spark pyspark

我已经通过pyodbc连接以块的形式读取数据:

import pandas as pd
import pyodbc
conn = pyodbc.connect("Some connection Details")
sql = "SELECT * from TABLES;"
df1 = pd.read_sql(sql,conn,chunksize=10)

现在我想用以下内容将所有这些块读入一个火花数据帧:

i = 0
for chunk in df1:
    if i==0:
        df2 = sqlContext.createDataFrame(chunk)
    else:
        df2.unionAll(sqlContext.createDataFrame(chunk))
    i = i+1

问题是,当我执行df2.count()时,我得到的结果为10,这意味着只有i = 0的情况才有效。这是unionAll的一个错误。我在这里做错了吗?

1 个答案:

答案 0 :(得分:4)

.unionAll()的文档指出它返回一个新的数据框,因此您必须分配回df2 DataFrame:

i = 0
for chunk in df1:
    if i==0:
        df2 = sqlContext.createDataFrame(chunk)
    else:
        df2 = df2.unionAll(sqlContext.createDataFrame(chunk))
    i = i+1

此外,您可以使用enumerate()来避免自己管理i变量:

for i,chunk in enumerate(df1):
    if i == 0:
        df2 = sqlContext.createDataFrame(chunk)
    else:
        df2 = df2.unionAll(sqlContext.createDataFrame(chunk))

此外,.unionAll()的文档指出.unionAll()已被弃用,现在您应该使用.union(),其行为类似于SQL中的UNION ALL:

for i,chunk in enumerate(df1):
    if i == 0:
        df2 = sqlContext.createDataFrame(chunk)
    else:
        df2 = df2.union(sqlContext.createDataFrame(chunk))

编辑:
此外,我会停止进一步说,但在我进一步说之前不要说:因为@ zero323说让我们不在循环中使用.union()。让我们改为:

def unionAll(*dfs):
    ' by @zero323 from here: http://stackoverflow.com/a/33744540/42346 '
    first, *rest = dfs  # Python 3.x, for 2.x you'll have to unpack manually
    return first.sql_ctx.createDataFrame(
        first.sql_ctx._sc.union([df.rdd for df in dfs]),
        first.schema
    )

df_list = []
for chunk in df1:
    df_list.append(sqlContext.createDataFrame(chunk))

df_all = unionAll(df_list)
相关问题