How to add items from a list to nested lists in a data frame one by one

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]

I have a pandas framework and would like to add each element of list C to each of the nested lists of B, maintaining the structure, so the resulting framework:

'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]]
+4
source share
3 answers

Mybe has a more elegant solution, but it works :-)

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

More efficient solution based on timgebs comments (thanks!):

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
+3
source

This is an alternative method using itertools.

The idea is to flatten the list of lists, add your data, and then again split by the information that you saved in the number of lists on each line.

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]]
+2
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]
0

Source: https://habr.com/ru/post/1695492/


All Articles