Транспонировать DataFrame на основе количества столбцов со значениями - PullRequest
1 голос
/ 02 октября 2019

Я ищу транспонировать столбцы со значениями, а не NaN в столбцах с номерами 1-11. При каждом транспонировании столбца мне нужно скопировать «идентификатор оператора» и остальные данные в каждую новую строку. Возможно, для каждого «идентификатора оператора» может быть до 11 записей или только 1.

Я пробовал df.T и df.stack ().

df.head()
Out[7]: 
    Operator id  CountryID                  1                   2        3    4    5    6    7    8    9   10   11
0    john.smith      376.0     jake.sha.human                 NaN      NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1    john.wayne      826.0  sambaser@fake.com                 NaN      NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2    mike.evans      840.0    ardenn@fake.com  isabellac@fake.com  sam.cha  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  sarah.wagner      356.0    nathan@fake.com                 NaN      NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
4    two.chains      784.0        AR@fake.com         hr@fake.com      NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
    Operator id  CountryID               TransCol
0    john.smith      376.0          jake.sha.human
1    john.wayne      826.0          sambaser@fake.com
2    mike.evans      840.0          ardenn@fake.com
3    mike.evans      840.0          isabellac@fake.com
4    mike.evans      840.0          sam.cha
5    sarah.wagner    356.0          nathan@fake.com
6    two.chains      784.0          AR@fake.com
7    two.chains      784.0          hr@fake.com

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Это melt:

df.melt(id_vars=['Operator id', 'CountryID']).drop('variable', 1).dropna()

Выход:

     Operator id  CountryID               value
0     john.smith      376.0      jake.sha.human
1     john.wayne      826.0   sambaser@fake.com
2     mike.evans      840.0     ardenn@fake.com
3   sarah.wagner      356.0     nathan@fake.com
4     two.chains      784.0         AR@fake.com
7     mike.evans      840.0  isabellac@fake.com
9     two.chains      784.0         hr@fake.com
12    mike.evans      840.0             sam.cha

Или stack:

(df.set_index(['Operator id', 'CountryID'])
   .stack()
   .reset_index(level=-1, drop=True)
   .reset_index(name='TransCol')
)

Выход:

    Operator id  CountryID            TransCol
0    john.smith      376.0      jake.sha.human
1    john.wayne      826.0   sambaser@fake.com
2    mike.evans      840.0     ardenn@fake.com
3    mike.evans      840.0  isabellac@fake.com
4    mike.evans      840.0             sam.cha
5  sarah.wagner      356.0     nathan@fake.com
6    two.chains      784.0         AR@fake.com
7    two.chains      784.0         hr@fake.com
0 голосов
/ 02 октября 2019

Я уверен, что есть более удобный способ сделать это с помощью stack (), но вы можете сделать что-то очень простое, например:

id_cols = ['Operator id', 'CountryID']
final_df = df[id_cols].drop_duplicates()
for col in [c for c in df.columns if c not in id_cols]:
    col_df = df[id_cols + [col].dropna().rename(columns={col: 'TransCol'})
    final_df = final_df.append(col_df, sort=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...