Как объединить две последовательные строки и сформировать новый столбец? - PullRequest
2 голосов
/ 08 мая 2019

У меня есть DF (собранный из бухгалтерского программного обеспечения), который выглядит следующим образом.


    Serial || Date || Particulars || Price
    --------------------------------------
      1    || 0308 || Andrew      || 100
      2    || NaN  || Gloves      || NaN
      3    || 0408 || Johnson     || 50
      4    || NaN  || Wicket      || NaN

Я хочу объединить 2 последовательные строки и создать новый столбец «Продукт» со значением «Особенности» 2-й строки. Ожидаемый результат должен выглядеть как ---

    Serial || Date || Particulars || Price || Product
    -------------------------------------------------
      1    || 0308 || Andrew      || 100   || Gloves
      3    || 0408 || Johnson     || 50    || Wicket

Как мне достичь этого с пандами?

Ответы [ 3 ]

4 голосов
/ 08 мая 2019

Эти ответы основаны на формате кадра данных, всегда представляющего пары строк, которые следуют одному и тому же шаблону, представленному OP.Первая строка показывает человека, вторая строка показывает продукт и дату, столбцы цен: NaN.

Использование shift, затем dropna

df.assign(Product=df.Particulars.shift(-1)).dropna()

   Serial   Date Particulars  Price Product
0       1  308.0      Andrew  100.0  Gloves
2       3  408.0     Johnson   50.0  Wicket

join

Та же самая вещь, но другая

df.join(df.Particulars.shift(-1).rename('Product')).dropna()

Подробности

По запросу

  • df.Particulars.shift(-1) объединяет всех членовСтолбец подробностей на одну строку назад

    0     Gloves
    1    Johnson
    2     Wicket
    3        NaN
    Name: Particulars, dtype: object
    
  • Когда я присваиваю его существующему фрейму данных df.assign(Product=df.Particulars.shift(-1)), он добавляет столбец с новым именем 'Product', значения которого представляют собой сдвинутые сведения.

       Serial   Date Particulars  Price  Product
    0       1  308.0      Andrew  100.0   Gloves
    1       2    NaN      Gloves    NaN  Johnson
    2       3  408.0     Johnson   50.0   Wicket
    3       4    NaN      Wicket    NaN      NaN
    
  • Осталось только отбросить строки со значениями NaN, и мы получили то, что представлено выше.


Вдохновленный ответом @ QuangHoang

Мне не нужно зависеть от dropna, если я нарежу каждую вторую строку

df.assign(Product=df.Particulars.shift(-1))[::2]

Или даже более кратко

df[::2].assign(Product=[*df.Particulars[1::2]])

Один из способов сделать это

Это был первый способ, о котором я подумал, и это брутто

i = np.flatnonzero(df.Price.notna())
j = i + 1

df.iloc[i].assign(Product=df.iloc[j].Particulars.values)

   Serial   Date Particulars  Price Product
0       1  308.0      Andrew  100.0  Gloves
2       3  408.0     Johnson   50.0  Wicket
1 голос
/ 08 мая 2019

Попробуйте shift и отбросьте четные строки:

df['Product'] = df['Particulars'].shift(-1)
df = df.loc[0:len(df):2]
1 голос
/ 08 мая 2019

некрасиво, но просто:

ans = df[~pd.isna(df.Date)].copy()
ans['product'] = df[pd.isna(df.Date)].Particulars.values

вывод

        Date  Particulars  Price  product
Serial                                  
1       308.0      Andrew  100.0  Gloves
3       408.0     Johnson   50.0  Wicket
...