我有一个中等大(约60,000行乘15列)csv文件,我正在与熊猫一起工作.每行代表一个人并包含个人数据.我想匿名呈现数据.我想要这样做的一种方法是替换特殊列中罕见的值.我最初尝试这样做如下:
def clean_data(entry):
if df[df.column_name == entry].index.size < 10:
return 'RARE_VALUE'
else:
return entry
df.new_column_name = df.column_name.apply(clean_data)
Run Code Online (Sandbox Code Playgroud)
但每次运行它都冻结了我的系统.不幸的是,这意味着我没有有用的调试数据.有谁知道这样做的正确方法?该列包含字符串和空值.
我想你想组合列名:
g = df.groupby('column_name')
Run Code Online (Sandbox Code Playgroud)
例如,您可以使用过滤器仅返回在column_name中出现超过10次的行的行:
g.filter(lambda x: len(x) >= 10)
Run Code Online (Sandbox Code Playgroud)
要使用'RARE_VALUE'覆盖列,您可以使用transform(为每个组计算一次结果,并适当地展开它):
df.loc[g[col].transform(lambda x: len(x) < 10).astype(bool), col] = 'RARE_VALUE'
Run Code Online (Sandbox Code Playgroud)
正如DSM指出的那样,以下技巧要快得多:
df.loc[df[col].value_counts()[df[col]].values < 10, col] = "RARE_VALUE"
Run Code Online (Sandbox Code Playgroud)
这里有一些时间信息(以显示DSM的解决方案是多么令人印象深刻!):
In [21]: g = pd.DataFrame(np.random.randint(1, 100, (1000, 2))).groupby(0)
In [22]: %timeit g.filter(lambda x: len(x) >= 10)
10 loops, best of 3: 67.2 ms per loop
In [23]: %timeit df.loc[g[1].transform(lambda x: len(x) < 10).values.astype(bool), 1]
10 loops, best of 3: 44.6 ms per loop
In [24]: %timeit df.loc[df[1].value_counts()[df[1]].values < 10, 1]
1000 loops, best of 3: 1.57 ms per loop
Run Code Online (Sandbox Code Playgroud)