【问题标题】:How to append elements from a list into nested lists in a dataframe one by one如何将列表中的元素一一追加到数据框中的嵌套列表中
【发布时间】:2018-09-07 16:50:53
【问题描述】:
import pandas as pd

d = {'A': [1,2,3,4], 'B': [[[1,2],[2,3]],[[3,4],[2,5]],[[5,6],[5,6],[5,6]],[7,8]]}

df = pd.DataFrame(data=d)

C = [1,2,3,4,5,6,7,8]

我有一个 pandas 数据框,并希望将 C 列表的每个元素附加到 B 的每个嵌套列表中,维护结构,以便生成的数据框为:

'A': [1,2,3,4]
'B': [[[1,2,1],[2,3,2]],[[3,4,3],[2,5,4]],[[5,6,5],[5,6,6],[5,6,7]],[7,8,8]]

【问题讨论】:

    标签: python list pandas


    【解决方案1】:
    d = {'A': [1,2,3,4], 'B': [[[1,2],[2,3]],[[3,4],[2,5]],[[5,6],[5,6],[5,6]],[7,8]]}
    
    df = pd.DataFrame(data=d)
    
    C = [1,2,3,4,5,6,7,8]
    
    df['B_len'] = df.B.apply(len)
    df['B_len_cumsum']=df.B_len.cumsum()
    df['C'] = df.apply(lambda row: C[row['B_len_cumsum']-row['B_len']:row['B_len_cumsum']], axis=1)
    df['B'] = df.B.apply(lambda x: [x] if type(x[0])==int else x)
    for x,y in zip(df.B,df.C):
            for xx,yy in zip(x,y):
                xx.append(yy)
    df
    

    输出:

       A                                  B  B_len  B_len_cumsum          C
    0  1             [[1, 2, 1], [2, 3, 2]]      2             2     [1, 2]
    1  2             [[3, 4, 3], [2, 5, 4]]      2             4     [3, 4]
    2  3  [[5, 6, 5], [5, 6, 6], [5, 6, 7]]      3             7  [5, 6, 7]
    3  4                        [[7, 8, 8]]      2             9        [8]
    

    【讨论】:

      【解决方案2】:

      这是使用itertools 的替代方法。

      这个想法是扁平化列表列表,附加数据,然后通过存储在每行列表数量上的信息再次拆分。

      from itertools import chain, accumulate
      import pandas as pd
      
      d = {'A': [1,2,3,4], 'B': [[[1,2],[2,3]],[[3,4],[2,5]],[[5,6],[5,6],[5,6]],[[7,8]]]}
      df = pd.DataFrame(data=d)
      C = [1,2,3,4,5,6,7,8]
      
      acc = [0] + list(accumulate(map(len, B)))
      
      lst = [j+[C[i]] for i, j in enumerate(chain.from_iterable(df['B']))]
      
      df['B'] = [lst[x:y] for x, y in zip(acc, acc[1:])]
      

      请注意,我对输入进行了重要更改:B 系列的最后一个元素是列表列表,就像所有其他元素一样。为了保持一致性,无论如何我都会推荐这个。

      结果

         A                                  B
      0  1             [[1, 2, 1], [2, 3, 2]]
      1  2             [[3, 4, 3], [2, 5, 4]]
      2  3  [[5, 6, 5], [5, 6, 6], [5, 6, 7]]
      3  4                        [[7, 8, 8]]
      

      【讨论】:

        【解决方案3】:

        Mybe 有一个更优雅的解决方案,但这可行:-)

        for i in d['B']:
            for j in i:
                if (isinstance(j, list)):
                    j.append(C.pop(0))
                else:
                    i.append(C.pop(0))
                    break
        

        基于 timgebs 评论的更高效的解决方案(谢谢!):

        f = iter(C)
        for i in d['B']:
            for j in i:
                if (isinstance(j, list)):
                    j.append(next(f))
                else:
                    i.append(next(f))
                    break
        

        【讨论】:

        • 考虑通过C 从listiterator 获取next 元素,这样您就不必在每次迭代中执行O(n) pop 操作。
        猜你喜欢
        • 2022-07-31
        • 2020-03-06
        • 1970-01-01
        • 1970-01-01
        • 2021-12-11
        • 2021-11-30
        • 2015-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多