Как разделить столбец панд данных в разных строках в зависимости от некоторых условий? - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь разделить один столбец DataFrame панд на несколько строк.

ДАННЫЕ: Входной кадр данных будет выглядеть ниже:

sports_name,player_name,player_country,player_average
football,XYZ,US,"[['1', '62.58'], ['2', '25.34'],['3', '88.35'],['4', '59.39']]"
football,ABC,US,"[['1', '56.61'], ['2', '52.63'],['3', 'NA'],['4', '44.32'],['5', '39.69']]"
cricket,PQR,IND,"[['1', '98.73'], ['2', '72.62'],['3', '71.53'],['4', '73.72']]"
cricket,LMN,IND,"[['1', '72.52'], ['2', '71.82'],['3', '-'],['4', '62.72'],['5', '73.83']]"

ДАННЫЕ:

  1. Столбец, который нам нужно разделить на несколько строк: player_average .
  2. Этот столбец "Player_average" содержит строковое значение, представляющее собой список из нескольких списков.
  3. Список всегда будет содержать два значения. Первый - "player_match", а второй - "player_average".
  4. Значение player_average может содержать «NA» или «-» или что-то еще.

Требования:

  1. "imum_average "- одно целочисленное значение.
  2. Я хочу, чтобы среднее значение каждого матча игрока было больше, чем "minumum_average".

Вывод: Выходной фрейм данных должен выглядеть ниже

sports_name,player_name,player_country,player_match,player_average
football,XYZ,US,1,62.58
football,XYZ,US,3,88.35
football,XYZ,US,4,59.39
football,ABC,US,1,56.61
football,ABC,US,2,52.63
cricket,PQR,IND,1,98.73
cricket,PQR,IND,2,72.62
cricket,PQR,IND,3,71.53
cricket,PQR,IND,4,73.72
cricket,LMN,IND,1,72.52
cricket,LMN,IND,2,71.82
cricket,LMN,IND,4,62.72
cricket,LMN,IND,5,73.82

РЕДАКТИРОВАТЬ:

Убедитесь, что данные очень большие. Может содержать ~ 20 000 массивов в player_average и ~ 10 000 000 строк.

1 Ответ

0 голосов
/ 09 мая 2018

Скажем, вы начинаете с

import ast
as_lists = pd.concat(
    [df, pd.DataFrame(df.player_average.apply(ast.literal_eval).tolist())],
    axis=1).drop('player_average', axis=1)
>>> as_lists
    sports_name player_name player_country  0   1   2   3   4
0   football    XYZ US  [1, 62.58]  [2, 25.34]  [3, 88.35]  [4, 59.39]  None
1   football    ABC US  [1, 56.61]  [2, 52.63]  [3, NA] [4, 44.32]  [5, 39.69]
2   cricket PQR IND [1, 98.73]  [2, 72.62]  [3, 71.53]  [4, 73.72]  None
3   cricket LMN IND [1, 72.52]  [2, 71.82]  [3, -]  [4, 62.72]  [5, 73.83]

Теперь расплавьте его в соответствии с тем, является ли столбец числом

melted = as_lists.melt(
    id_vars=[c for c in as_lists.columns if not isinstance(c, int)], 
    value_vars=[c for c in as_lists.columns if isinstance(c, int)]).dropna()

Разделите последний столбец и добавьте его:

final = pd.merge(df, melted)[['sports_name', 'player_name', 'player_country', 'value']]
>>> final.head()
    sports_name player_name player_country  value
0   football    XYZ US  [1, 62.58]
1   football    XYZ US  [2, 25.34]
2   football    XYZ US  [3, 88.35]
3   football    XYZ US  [4, 59.39]
4   football    ABC US  [1, 56.61]

Теперь просто отбросьте плохие строки:

final = final[~final.value.astype(str).str.contains(r'-|NA')]

final.head ()

и разделить последний столбец:

>>> pd.concat([
    final, 
    pd.DataFrame(final.value.values.tolist(), index=final.index, columns=['player_match', 'player_average'])],
axis=1).drop('value', axis=1)
    sports_name player_name player_country  player_match    player_average
0   football    XYZ US  1   62.58
1   football    XYZ US  2   25.34
2   football    XYZ US  3   88.35
3   football    XYZ US  4   59.39
4   football    ABC US  1   56.61
5   football    ABC US  2   52.63
7   football    ABC US  4   44.32
8   football    ABC US  5   39.69
9   cricket PQR IND 1   98.73
10  cricket PQR IND 2   72.62
11  cricket PQR IND 3   71.53
12  cricket PQR IND 4   73.72
13  cricket LMN IND 1   72.52
14  cricket LMN IND 2   71.82
16  cricket LMN IND 4   62.72
17  cricket LMN IND 5   73.83
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...