我有一个像这样的熊猫数据框:
import pandas as pd
data = {'VAR1': ['A', 'A', 'A', 'A','B', 'B'],
'VAR2': ['C', 'V', 'C', 'C','V', 'D']}
frame = pd.DataFrame(data)
从根本上说,我需要重新编码每个变量。重新编码将如下工作:计算每列的不同值的计数,如果计数大于或等于阈值,则保留原始值,否则设置新值“X”。如果阈值为3,那么这就是它需要的样子。
data2 = {'VAR3': ['A', 'A', 'A', 'A','X', 'X'],
'VAR4': ['C', 'X', 'C', 'C','X', 'X']}
frame2 = pd.DataFrame(data2)
这是所需的输出,原始数据合并到重新编码的数据。
pd.merge(frame, frame2, left_index=True, right_index=True)
我是Python的新手,虽然Python for Data Analysis这本书对我很有帮助,但我仍然无法弄清楚如何以简单的方式实现所需的结果。 任何帮助将不胜感激!
答案 0 :(得分:3)
单独拍摄每一列。按值对其进行分组,并使用组上的filter
方法将NaN
替换为少于3个值的任何组。然后将这些NaNs
替换为X
。
你可以在一个列表理解中完成所有这些,但为了清楚起见,我定义了一个recode
函数来完成所有实质性的工作。
In [38]: def recode(s, threshold):
....: return s.groupby(s).filter(lambda x: x.count() >= threshold, dropna=False).fillna(value='X')
....:
应用于每个列,然后将列重新组合为一个新的DataFrame ....
In [39]: frame2 = pd.concat([recode(frame[col], 3) for col in frame], axis=1)
In [40]: frame2
Out[40]:
VAR1 VAR2
0 A C
1 A X
2 A C
3 A C
4 X X
5 X X
而且,可以肯定的是,您可以像在问题中表达的那样合并原始帧和重新编码的帧:
In [27]: pd.merge(frame, frame2, left_index=True, right_index=True)
Out[27]:
VAR1_x VAR2_x VAR1_y VAR2_y
0 A C A C
1 A V A X
2 A C A C
3 A C A C
4 B V X X
5 B D X X
修改:对pandas版本使用此等效的解决方法< 0.12:
def recode(s, threshold):
b = s.groupby(s).transform(lambda x: x.count() >= threshold).astype('bool') # True/False
s[~b] = 'X'
return s