【问题标题】:Converting pandas Dataframe with Numpy values to pysparkSQL.DataFrame将带有 Numpy 值的 pandas Dataframe 转换为 pysparkSQL.DataFrame
【发布时间】:2018-01-06 18:51:04
【问题描述】:

我使用 random.int 方法创建了一个 2 列 pandas df 来生成应用 groupby 操作的第二个两列数据框。 df.col1 是一系列列表,df.col2 是一系列整数,列表内的元素是type 'numpy.int64',第二列的元素也是一样,是随机的结果.int.

df.a        df.b
3            7
5            2
1            8
...

groupby operations 

df.col1        df.col2
[1,2,3...]    1
[2,5,6...]    2
[6,4,....]    3
...

当我尝试使用 spark.createDataFrame(df) 来创建 pyspark.sql 数据框时,我收到此错误: 类型错误:不支持类型:类型“numpy.int64”。

回到 df 生成,我尝试了不同的方法将元素从 numpy.int64 转换为 python int,但没有一个主题起作用:

np_list = np.random.randint(0,2500, size = (10000,2)).astype(IntegerType)
df = pd.DataFrame(np_list,columns = list('ab'), dtype = 'int')

我也尝试使用 lambda x: int(x) 或 x.item() 进行映射,但类型仍然是 'numpy.int64'。

根据 pyspark.sql 文档,应该可以加载 pandas 数据帧,但是当它带有 numpy 值时似乎不兼容。 有什么提示吗?

谢谢!

【问题讨论】:

    标签: python pandas numpy pyspark apache-spark-sql


    【解决方案1】:

    好吧,你的做法是行不通的。如果你有这样的事情。由于第一列,您将收到错误消息。 Spark 不理解类型为 numpy.int64 的列表

    df.col1        df.col2
    [1,2,3...]    1
    [2,5,6...]    2
    [6,4,....]    3
    ...
    

    如果你有这样的事情。这个应该没问题的。

    df.a        df.b
    3            7
    5            2
    1            8
    

    就你的代码而言,试试这个:

    np_list = np.random.randint(0,2500, size = (10000,2))
    df = pd.DataFrame(np_list,columns = list('ab'))
    spark_df = spark.createDataFrame(df)
    

    您实际上不需要再次将其转换为int,如果您想明确地这样做,那么它就是array.astype(int)。然后就做spark_df.head。这应该可行!

    【讨论】:

    • 谢谢@DatTran,这行得通。但是我要转换的 df 是第一个(女巫列 co1 和 col2 和列表)而不是第二个;这就是为什么我试图在另一个数据框中强制从“numpy.int64”转换为“python int”。
    • @csbr 再次在这里......你需要接受那些回答 ppl 提供你解决你的问题
    【解决方案2】:

    这远不是一个完美的解决方案,但这是我在生产中实际运行以获得结果的方法:

      for col_name in ['integer column', 'other int column']:
        df3[col_name] = pd.to_numeric(df3[col_name], downcast='integer').astype('Int64')
    
      def df_generator(df_in: pd.DataFrame) -> Generator[list, None, None]:
        # As PySpark won't accept numpy.Int64, do the stupid thing and iterate entire dataframe to
        # do any type conversion by ourselves.
        for row_idx, row in df_in.iterrows():
          row_out = []
          for data in row:
            if isinstance(data, str):
              row_out.append(data)
            elif data is None or data is pd.NA:
              row_out.append(None)
            else:
              row_out.append(int(data))
          yield row_out
              
      spark_df = spark_session.createDataFrame(df_generator(df3), schema=schema)
    

    首先,我将已知列中包含整数的字符串中的导入数据强制转换为数字,并对其进行另一次 Int64 强制。

    然后将整个 Pandas 数据帧转换为 PySpark 数据帧。这是一个简单的生成器函数,用于迭代整个 Pandas 数据帧(既不鼓励又愚蠢)返回与具有正确数据类型的列表完全相同的数据。

    我希望 PySpark 团队能够解决这个缺点,以简化对 Pandas 数据的处理。

    【讨论】:

      猜你喜欢
      • 2019-08-04
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      相关资源
      最近更新 更多