pd.DataFrame.apply可以附加由lambda函数返回的数据帧吗?

时间:2019-10-07 21:54:21

标签: pandas

我正在尝试转换此代码-

    for item in data['item'].unique():
     response = process_item(item) # returns List[Dict[Text, Optional[int]]]
     response = pd.DataFrame(response)
     response['item'] = item
     final_response = final_response.append(response)

类似-

    data = data[['item']].drop_duplicates().reset_index(drop=True)
    final_response = data[['item']].apply(lambda x: process_item(x))
    final_response['item'] = data['item']

想法是稍后使用dask并行处理数据帧上的应用。

我尝试从process_item返回pd.DataFrame,但出现ValueError:如果使用所有标量值,则必须传递索引

响应看起来像这样-

   A       B         C
0  456  foo bar     123.0

我该如何解决ValueError问题,并且我认为apply会将来自process_item的输出df附加到final_response正确吗?

编辑:添加了示例数据

包装pd.Series中process_item的输出-

#output from process_item
{'A': [456, 789], 'B': ['foo bar', 'dog bar'], 'C': [123.0, 160.0]}

#printing ouput in pd.Series
A        [456, 789]
B        [foo bar, dog bar]
C        [123.0, 160.0]

#Adding a new 'item' column
          A             B           C                    item
0  [456, 789]  [foo bar, dog bar]  [123.0, 160.0]         bar

下面是第一个代码段-

#output from process_item
{'A': [456, 789], 'B': ['foo bar', 'dog bar'], 'C': [123.0, 160.0]}

#output from process_item in pd.DataFrame
    A      B          C
0  456  foo bar     123.0
1  789  dog bar     160.0

#Adding a new 'item' column
            A              B               C           item
0          456          foo bar          123.0         bar
1          789          dog bar          160.0         bar

我需要按照第二个示例添加项目。

编辑(已解决): 我终于能够通过@yugandhar共享的split_dataframe_rows函数进行一些更改来使它起作用。 1.计算max_split-它计算的是新添加的'item'列的长度,其中包含'bar',因此求值为3,因为其他列表仅包含两个元素,所以添加了类型检查。 2. split_rows[column_selector].pop(0)在'item'列抛出错误,表明str对象没有pop属性。因此,添加了仅在列表中才执行此操作的检查,否则仅进行分配。还测试了您的更新解决方案,并且工作正常。不知道为什么这些问题没有出现在colab上,可能是python版本的差异或其他原因。 我尝试了爆炸,但对我也不起作用,我想我没有使用0.25熊猫。我将继续寻找更好的分割方法。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,那么您需要进行以下更改:
返回pd.Series而不是pd.DataFrame,
使用data ['item']获取值(这就是您并在列中
data [['item']]获取具有索引列和项目列的数据框
Working Solution

答案 1 :(得分:0)

考虑列表理解以构建要在最后连接的数据帧列表:

dfs = [(pd.DataFrame(process_item(i)) 
          .assign(item = i) 
       ) for i in data['item'].unique()]

final_df = pd.concat(df_list, ignore_index=True)