파이썬 판다스 데이터프레임에서 NaN 이 아닌 값의 갯수를 세기 + 약간의 조건
조회수 388회
df에서 dd 인덱스 순서대로 NaN 제외한 열별로 value 개수 총합을 구하려고 하는데요
이전 df value값이 NaN이면 그 행은 제외하고 카운팅 되면 좋겠어요.
하드코딩한건 아래와 같습니다.
예시에선 4개 열뿐이지만 더 개수가 많아질 경우를 대비해서 lambda apply 써서 간단하게 하고 싶은데 어렵네요.
안된다면 for 문이라도요.
02 -> 5개(foo, fid, bar, cute, you)
06 -> 4개(q, d, e, vd)
07 -> 2개(g, z)
08 -> 1개(a)
[5, 4, 2, 1] 로 결과값이 나오면 좋겠는데 어떻게 해야하는지 모르겠네요 ..
import pandas as pd
import numpy as np
dd = {'02':1,'06':2,'07':3,'08':4}
dd = pd.DataFrame.from_dict(dd, orient = 'index', columns = ['step'])
print(dd)
left = pd.DataFrame({'02':['foo','fid','bar','cute'], '06':['q','d','e','vd']})
right = pd.DataFrame({'02':['foo','you','bar'],'07':['g','v','z'], '08':['a','b','c']})
df = pd.merge(left,right, on=['02'], how='outer')
df.iloc[2,3] = np.nan
print()
print(df)
df2 = df.loc[df['06'].notnull()]
df3 = df2.loc[df2['07'].notnull()]
df4 = df3.loc[df3['08'].notnull()]
a = df['02'].notnull().sum()
b = df2['06'].notnull().sum()
c = df3['07'].notnull().sum()
d = df4['08'].notnull().sum()
print()
print([a,b,c,d])
1 답변
-
- dataframe 전체에 대해 notnull() 을 해서 boolean 테이블을 만듭니다.
- 여기서 단순히 컬럼별로 na 가 아닌 데이터의 갯수를 새려면,
df.sum(axis=0)
으로 충분합니다. 하지만 조건이 있습니다. - 조건에 따라 컬럼명을 정렬하고,
- 연달아 나오는 컬럼명을
zip(cols[:-1], cols[1:])
으로 두개씩 가져옵니다. - 가져온 두컬럼에 대해서 순차적으로 논리적 AND 연산을 합니다.
- 연산후에
df.sum(axis=0)
으로 결과를 확인합니다.
import pandas as pd import numpy as np dd = {"02": 1, "06": 2, "07": 3, "08": 4} dd_df = pd.DataFrame.from_dict(dd, orient="index", columns=["step"]) print(dd_df) left = pd.DataFrame({"02": ["foo", "fid", "bar", "cute"], "06": ["q", "d", "e", "vd"]}) right = pd.DataFrame({"02": ["foo", "you", "bar"], "07": ["g", "v", "z"], "08": ["a", "b", "c"]}) df = pd.merge(left, right, on=["02"], how="outer") df.iloc[2, 3] = np.nan print() print(df) """ df2 = df.loc[df['06'].notnull()] df3 = df2.loc[df2['07'].notnull()] df4 = df3.loc[df3['08'].notnull()] a = df['02'].notnull().sum() b = df2['06'].notnull().sum() c = df3['07'].notnull().sum() d = df4['08'].notnull().sum() print() print([a,b,c,d]) """ df = df.notnull() print(df) sorted_col = sorted(dd.keys(), key=lambda c: dd[c]) # print(sorted_col) for col1, col2 in zip(sorted_col[:-1], sorted_col[1:]): df[col2] = df[col1] & df[col2] print(f"-- after ANDing {col1} and {col2} --") print(df) print(df.sum(axis=0))
step 02 1 06 2 07 3 08 4 02 06 07 08 0 foo q g a 1 fid d NaN NaN 2 bar e z NaN 3 cute vd NaN NaN 4 you NaN v b 02 06 07 08 0 True True True True 1 True True False False 2 True True True False 3 True True False False 4 True False True True -- after ANDing 02 and 06 -- 02 06 07 08 0 True True True True 1 True True False False 2 True True True False 3 True True False False 4 True False True True -- after ANDing 06 and 07 -- 02 06 07 08 0 True True True True 1 True True False False 2 True True True False 3 True True False False 4 True False False True -- after ANDing 07 and 08 -- 02 06 07 08 0 True True True True 1 True True False False 2 True True True False 3 True True False False 4 True False False False 02 5 06 4 07 2 08 1 dtype: int64
댓글 입력