Как сжать фрейм данных, удалив столбцы, содержащие значение «NaN», между столбцами, имеющими значение? - PullRequest
0 голосов
/ 07 июня 2019

Я сейчас следую за ответом здесь .В основном это работало, но когда я просмотрел весь фрейм данных, я увидел, что есть столбцы, которые содержат значения 'NaN' между столбцами, которые содержат значение.

Например, я продолжаю получать результат чего-то вроде этого:

     ID | 0  | 1  |   2  |  3   | 4   | 5  | 6  |  7   |  8   | 9
300 1001|1001|1002|  NaN | NaN  | NaN |1001|1002|  NaN | NaN  | NaN   
301 1010|1010|NaN |  NaN | 1000 | 2000|1234| NaN|  NaN | 1213 | 1415
302 1100|1234|5678| 9101 | 1121 | 3141|2345|6789| 1011 | 1617 | 1819
303 1000|2001|9876|  NaN | NaN  | NaN |1001|1002|  NaN | NaN  | NaN  

Есть ли способ удалить те ячейки, которые содержат NaN, так что результат будет выглядеть так:

     ID | 0  | 1  |   2  |  3   | 4   | 5  | 6  |  7   |  8   | 9
300 1001|1001|1002|  1001| 1002 | NaN |NaN | NaN|  NaN | NaN  | NaN   
301 1010|1010|1000|  2000| 1234 | 1213|1415| NaN|  NaN | NaN  | NaN
302 1100|1234|5678|  9101| 1121 | 3141|2345|6789| 1011 | 1617 | 1819
303 1000|2001|9876|  1001| 1002 | NaN |NaN |NaN |  NaN | NaN  | NaN 

Ответы [ 3 ]

3 голосов
/ 07 июня 2019

Использование pd.DataFrame.iterrows с pd.concat:

import pandas as pd

df[df.columns] = pd.concat([s.dropna().reset_index(drop=True) for i,s in df.iterrows()], 1).T

Выход:

         ID     0     1     2     3     4     5     6     7     8     9
0  300 1001  1001  1002  1001  1002   NaN   NaN   NaN   NaN   NaN   NaN
1  301 1010  1010  1000  2000  1234  1213  1415   NaN   NaN   NaN   NaN
2  302 1100  1234  5678  9101  1121  3141  2345  6789  1011  1617  1819
3  303 1000  2001  9876  1001  1002   NaN   NaN   NaN   NaN   NaN   NaN
1 голос
/ 07 июня 2019

сначала отсортируйте каждую строку по ключу np.isnan

import pandas as pd
import numpy as np
raw = [ [1,2,np.nan,3,np.nan],
        [1,np.nan,3,2,7]]
original = pd.DataFrame(raw)
s = original.apply(lambda x:pd.Series(sorted(x,key=np.isnan)),axis=1)
print(s)
0 голосов
/ 07 июня 2019

Используйте justify , если важна производительность:

df = pd.DataFrame(justify(df.to_numpy(), invalid_val=np.nan), 
                  index=df.index, 
                  columns=df.columns)
print (df)
         ID       0       1       2       3       4       5       6       7  \
300  1001.0  1001.0  1002.0  1001.0  1002.0     NaN     NaN     NaN     NaN   
301  1010.0  1010.0  1000.0  2000.0  1234.0  1213.0  1415.0     NaN     NaN   
302  1100.0  1234.0  5678.0  9101.0  1121.0  3141.0  2345.0  6789.0  1011.0   
303  1000.0  2001.0  9876.0  1001.0  1002.0     NaN     NaN     NaN     NaN   

          8       9  
300     NaN     NaN  
301     NaN     NaN  
302  1617.0  1819.0  
303     NaN     NaN  

Если первый столбец должен быть не числовым или возможные пропущенные значения, решение применяется ко всем столбцам без первого и добавляется первый столбец позжеinsert:

df.columns = df.columns[:1].tolist() + df.columns[1:].astype(int).tolist()

arr = justify(df.to_numpy()[:, 1:], invalid_val=np.nan)
df1 = pd.DataFrame(arr, index=df.index, columns=df.columns[1:] + 1)
df1.insert(0,'ID', df['ID'])
print (df1)
       ID       1       2       3       4       5       6       7       8  \
300  1001  1001.0  1002.0  1001.0  1002.0     NaN     NaN     NaN     NaN   
301  1010  1010.0  1000.0  2000.0  1234.0  1213.0  1415.0     NaN     NaN   
302  1100  1234.0  5678.0  9101.0  1121.0  3141.0  2345.0  6789.0  1011.0   
303  1000  2001.0  9876.0  1001.0  1002.0     NaN     NaN     NaN     NaN   

          9      10  
300     NaN     NaN  
301     NaN     NaN  
302  1617.0  1819.0  
303     NaN     NaN  
...