Разделение данных строк Pandas на несколько строк без добавления столбцов

#python #pandas #dataframe

Вопрос:

У меня есть некоторые данные по американскому футболу в фрейме данных, как показано ниже:

 df = pd.DataFrame({'Green Bay Packers' : ['30-18-0', '5-37', '10-71' ],
                    'Chicago Bears' : ['45-26-1', '5-20', '10-107']}, 
                 index=['Att - Comp - Int', 'Sacked - Yds Lost', 'Penalties - Yards'])
 
                     Green Bay Packers   Chicago Bears
Att - Comp - Int    30-18-0               45-26-1
Sacked - Yds Lost   5-37                    5-20
Penalties - Yards   10-71                  10-107
 

Вы можете видеть выше, что каждая строка содержит несколько точек данных, которые необходимо разделить.
Что я хотел бы сделать, так это найти способ разделить строки так, чтобы каждая точка данных была отдельной строкой. Конечный результат хотел бы, чтобы:

         Green Bay Packers   Chicago Bears
Att           30                45
Comp          18                26
Int            0                 1
Sacked         5                 5
Yds Lost      37                20
Penalties     10                10
Yards         71               107
 

Есть ли способ сделать это эффективно? Я попробовал несколько регулярных выражений, но это просто превратилось в беспорядок. Извините, если мое форматирование не идеально…2-й вопрос, когда-либо размещенный здесь.

Комментарии:

1. Преобразуйте значения в строку, а затем воссоздайте данные с соответствующими значениями. Вот что я бы сделал

Ответ №1:

Попробуй:

 df = df.reset_index().apply(lambda x: x.str.split("-"))
df = pd.DataFrame(
    {c: df[c].explode().str.strip() for c in df.columns},
).set_index("index")
df.index.name = None
print(df)
 

С принтами:

           Green Bay Packers Chicago Bears
Att                      30            45
Comp                     18            26
Int                       0             1
Sacked                    5             5
Yds Lost                 37            20
Penalties                10            10
Yards                    71           107
 

Ответ №2:

Сначала сбросьте индекс, затем сложите все столбцы и разделите их - , вы также можете дополнительно применить, чтобы удалить любые оставшиеся пробелы после использования разделения, затем снова распаковать, затем применить pd.Series.explode , наконец, сбросить индекс и удалить любой оставшийся неиспользованный столбец.

 out =  (df.reset_index()
        .stack().str.split('-').apply(lambda x:[i.strip() for i in x])
        .unstack()
        .apply(pd.Series.explode)
        .reset_index()
        .drop(columns='level_0'))

        index Green Bay Packers Chicago Bears
0        Att                 30            45
1       Comp                 18            26
2         Int                 0             1
3     Sacked                  5             5
4    Yds Lost                37            20
5  Penalties                 10            10
6       Yards                71           107
 

Ответ №3:

Предполагая, что у вас одинаковое количество разбиений для каждой строки, с pandas >= 1.3.0> вы можете разнести несколько столбцов одновременно:

 df = df.reset_index().apply(lambda s: s.str.split(' *- *'))
df.explode(df.columns.tolist()).set_index('index')

          Green Bay Packers Chicago Bears
index
Att                      30            45
Comp                     18            26
Int                       0             1
Sacked                    5             5
Yds Lost                 37            20
Penalties                10            10
Yards                    71           107
 

Ответ №4:

Используйте .apply() для каждого столбца (включая индекс) и для каждого столбца:

  • используется .str.split() для разделения точек данных и
  • используется .explode() для создания строк для каждого элемента разделенной точки данных
 df_out = (df.reset_index()
            .apply(lambda x: x.str.split(r's*-s*').explode())
            .set_index('index').rename_axis(index=None)
         )
 

Результат:

 print(df_out)

          Green Bay Packers Chicago Bears
Att                      30            45
Comp                     18            26
Int                       0             1
Sacked                    5             5
Yds Lost                 37            20
Penalties                10            10
Yards                    71           107