Панды объединяют строки в столбце

#python #pandas

#python #pandas

Вопрос:

Имея этот фрейм данных:

 A      B                 C    D 
Train  Superfast         10   20 
NaN    Convernient       NaN NaN
NaN    Newest model      NaN NaN
NaN    Year 2002/099     NaN NaN
Car    Fastest           20   30
NaN    Can be more fast  NaN NaN
NsN    Year/2020/AYD     NaN NaN
  

Можно ли сдвинуть строки в столбце B до строки, в которой есть оставшиеся значения в других столбцах?

 A      B                                                  C  D 
Train  Superfast Convernient Newest model Year 2002/099  10 20 
Car    Fastest Can be more fast Year/2020/AYD            20 30
  

Ответ №1:

Давайте используем cumsum для идентификации блоков и groupby на этом:

 blocks = df['C'].notna().cumsum()

agg_dict = {col:' '.join if col=='B' else 'first' for col in df}

df.groupby(blocks).agg(agg_dict).reset_index(drop=True)
  

Вывод:

        A                                                 B     C     D
0  Train  Superfast Convernient Newest model Year 2002/099  10.0  20.0
1    Car            Fastest Can be more fast Year/2020/AYD  20.0  30.0
  

Ответ №2:

Немного сложное решение, использующее только numpy , но работающее очень быстро для больших данных:

Попробуйте запустить его онлайн!

 import pandas as pd, numpy as np, math

df = pd.DataFrame([
    ['Train', 'Superfast', 10, 20],
    [np.nan, 'Convernient', np.nan, np.nan],
    [np.nan, 'Newest model', np.nan, np.nan],
    [np.nan, 'Year 2002/099', np.nan, np.nan],
    ['Car', 'Fastest', 20, 30],
    [np.nan, 'Can be more fast', np.nan, np.nan],
    [np.nan, 'Year/2020/AYD', np.nan, np.nan],
], columns = ['A', 'B', 'C', 'D'])

a = df.values
i = np.append(np.flatnonzero(~(a[:, 0] != a[:, 0])), a.shape[0])
b = a[i[:-1], :]
diffs = np.diff(i)
maxs = np.amax(diffs)
c = np.zeros([i.shape[0], maxs], dtype = np.str_)

begs, ends = i[:-1], i[1:]
for j in range(1, maxs):
    chosen = begs   j < ends
    b[chosen, 1]  = ' '   a[begs[chosen]   j, 1]

df = pd.DataFrame(b, columns = df.columns.values.tolist())
print(df)
  

Вывод кода:

        A                                                 B   C   D
0  Train  Superfast Convernient Newest model Year 2002/099  10  20
1    Car            Fastest Can be more fast Year/2020/AYD  20  30