2016-07-26 7 views
3

여러 변수 (온도, 압력 등)에 대해 다른 기상대에 기초한 데이터 집합파이썬 팬더 - NaN이 아닌 NaN이

stationID | Time | Temperature | Pressure |... 
----------+------+-------------+----------+ 
123  | 1 |  30  | 1010.5 | 
123  | 2 |  31  | 1009.0 | 
202  | 1 |  24  | NaN  | 
202  | 2 |  24.3 | NaN  | 
202  | 3 |  NaN  | 1000.3 | 
... 

난이 난 것의 수를 표시하는 변수 피봇 테이블을 구축 NaN이와 기상 관측소 당 비 NaN을, 등 그 수를 표시 할 피벗 테이블을 만들려면 :

내가 (성가신 방법으로) 작동하는, 지금까지 한 일을 보여 아래
stationID | nanStatus | Temperature | Pressure |... 
----------+-----------+-------------+----------+ 
123  | NaN  |  0  |  0 |  
      | nonNaN |  2  |  2 | 
202  | NaN  |  1  |  2 | 
      | nonNaN |  2  |  1 | 
... 

에 대한 온도. 그러나 위의 그림과 같이 두 변수 모두에서 어떻게 같은 결과를 얻을 수 있습니까?

import pandas as pd 
import bumpy as np 
df = pd.DataFrame({'stationID':[123,123,202,202,202], 'Time':[1,2,1,2,3],'Temperature':[30,31,24,24.3,np.nan],'Pressure':[1010.5,1009.0,np.nan,np.nan,1000.3]}) 

dfnull = df.isnull() 
dfnull['stationID'] = df['stationID'] 
dfnull['tempValue'] = df['Temperature'] 
dfnull.pivot_table(values=["tempValue"], index=["stationID","Temperature"], aggfunc=len,fill_value=0) 

출력은 다음과 같습니다

---------------------------------- 
         tempValue 
stationID | Temperature   
123  | False    2 
202  | False    2 
      | True     1 

답변

3

UPDATE : 감사 @root에 :

In [16]: df.groupby('stationID')[['Temperature','Pressure']].agg([nans, notnans]).astype(int).stack(level=1) 
Out[16]: 
        Temperature Pressure 
stationID 
123  nans    0   0 
      notnans   2   2 
202  nans    1   2 
      notnans   2   1 

원래 답 :

In [12]: %paste 
def nans(s): 
    return s.isnull().sum() 

def notnans(s): 
    return s.notnull().sum() 
## -- End pasted text -- 

In [37]: df.groupby('stationID')[['Temperature','Pressure']].agg([nans, notnans]).astype(np.int8) 
Out[37]: 
      Temperature   Pressure 
       nans notnans  nans notnans 
stationID 
123     0  2  0  2 
202     1  2  2  1 
+2

당신은'.stack으로 마무리 할 수 ​​있습니다 (레벨 = 1)' – root

+0

@root, 그래, 그거야, 감사합니다 제비! – MaxU

+0

굉장, @MaxU 및 @root! '.stack (level = 1)'은 케이크 위에 담겨있었습니다! (그냥 가장 가까운 정수로 출력을 반올림하는 방법이 있었으면 좋겠다 .' round'와'int'를 사용하여 시도했지만 작동하지 않았다.) – mmeclimate

0

이것이 가장 좋은 해결책은 아니지만 인정됩니다.

Results['Temperature'] = df.groupby(['stationID','TempNaN'])['Temperature'].apply(lambda x: x.shape[0]) 
Results['Pressure'] = df.groupby(['stationID','PresNaN'])['Pressure'].apply(lambda x: x.shape[0]) 

그리고 입력 : 결과 DataFrame에서

Results = pd.DataFrame(index=pd.MultiIndex.from_tuples(list(zip(*[sorted(list(df['stationID'].unique())*2),['NaN','NonNaN']*df['stationID'].nunique()])),names=['stationID','NaNStatus'])) 

스토어 귀하의 계산 : 그럼 MultiIndex를 사용하여 결과 DataFrame을 정의

df['TempNaN'] = df['Temperature'].apply(lambda x: 'NaN' if x!=x else 'NonNaN') 
df['PresNaN'] = df['Pressure'].apply(lambda x: 'NaN' if x!=x else 'NonNaN') 

: 먼저이 일시적으로 열 TempNaNPresNaN을 정의 0으로 공백 값 :

Results.fillna(value=0,inplace=True) 

더 쉬운 경우 열을 반복 할 수 있습니다. 예를 들어 :

Results = pd.DataFrame(index=pd.MultiIndex.from_tuples(list(zip(*[sorted(list(df['stationID'].unique())*2),['NaN','NonNaN']*df['stationID'].nunique()])),names=['stationID','NaNStatus'])) 
for col in ['Temperature','Pressure']: 
    df[col + 'NaN'] = df[col].apply(lambda x: 'NaN' if x!=x else 'NonNaN') 
    Results[col] = df.groupby(['stationID',col + 'NaN'])[col].apply(lambda x: x.shape[0]) 
    df.drop([col + 'NaN'],axis=1,inplace=True) 
Results.fillna(value=0,inplace=True) 
0
d = {'stationID':[], 'nanStatus':[], 'Temperature':[], 'Pressure':[]} 

for station_id, data in df.groupby(['stationID']): 

    temp_nans = data.isnull().Temperature.mean()*data.isnull().Temperature.count() 
    pres_nans = data.isnull().Pressure.mean()*data.isnull().Pressure.count() 

    d['stationID'].append(station_id) 
    d['nanStatus'].append('NaN') 
    d['Temperature'].append(temp_nans) 
    d['Pressure'].append(pres_nans) 

    d['stationID'].append(station_id) 
    d['nanStatus'].append('nonNaN') 
    d['Temperature'].append(data.isnull().Temperature.count() - temp_nans) 
    d['Pressure'].append(data.isnull().Pressure.count() - pres_nans) 

df2 = pd.DataFrame.from_dict(d) 
print(df2) 

결과는 다음과 같습니다

Pressure Temperature nanStatus stationID 
0  0.0   0.0  NaN  123 
1  2.0   2.0 nonNaN  123 
2  2.0   1.0  NaN  202 
3  1.0   2.0 nonNaN  202 
관련 문제