创建前n个值的dataframe的更有效方法-python
我有一个类别的数据框架,我需要通过将值限制在前n个类别来清理它。任何不在前n个类别中的值都应放在0(或“其他”)下 我尝试了下面的代码,它循环遍历列的每一行,然后遍历数据帧中的每一列,以检查该位置的值是否在该列的前n个值_计数中找到。如果是,则保留该值,如果不是,则替换为0 这种实现在技术上是可行的,但当行数很大时,运行时间太长。在熊猫/努比中,实现这一点的更快方法是什么创建前n个值的dataframe的更有效方法-python,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,我有一个类别的数据框架,我需要通过将值限制在前n个类别来清理它。任何不在前n个类别中的值都应放在0(或“其他”)下 我尝试了下面的代码,它循环遍历列的每一行,然后遍历数据帧中的每一列,以检查该位置的值是否在该列的前n个值_计数中找到。如果是,则保留该值,如果不是,则替换为0 这种实现在技术上是可行的,但当行数很大时,运行时间太长。在熊猫/努比中,实现这一点的更快方法是什么 z = pd.DataFrame(np.random.randint(1,4,size=(100000, 4))) x=pd
z = pd.DataFrame(np.random.randint(1,4,size=(100000, 4)))
x=pd.DataFrame()
n=10
for j in z:
for i in z[j].index:
if z.at[i,j] in z[j].value_counts().head(n).index.tolist():
x.at[i,j] = z.at[i,j]
else:
x.at[i,j]= 0
print(x)
我认为您可以使用自定义函数for top value和for boolean mask来替换循环列:
def f(x):
y = x.value_counts().head(n).index
return x.where(x.isin(y), 0)
print (z.apply(f))
什么是相同的:
print (z.apply(lambda x: x.where(x.isin(x.value_counts().head(n).index), 0)))
样本:
#N =100000
N = 10
np.random.seed(123)
z = pd.DataFrame(np.random.randint(1,4,size=(N, 4)))
print (z)
0 1 2 3
0 3 2 3 3
1 1 3 3 2
2 3 2 3 2
3 1 2 3 2
4 1 3 1 2
5 3 2 1 1
6 1 1 2 3
7 1 3 1 1
8 2 1 2 1
9 1 1 3 2
类似的解决方案包括:
x=pd.DataFrame()
n=2
for j in z:
for i in z[j].index:
if z.at[i,j] in z[j].value_counts().head(n).index.tolist():
x.at[i,j] = z.at[i,j]
else:
x.at[i,j]= 0
print(x)
0 1 2 3
0 3.0 2.0 3.0 0.0
1 1.0 3.0 3.0 2.0
2 3.0 2.0 3.0 2.0
3 1.0 2.0 3.0 2.0
4 1.0 3.0 1.0 2.0
5 3.0 2.0 1.0 1.0
6 1.0 0.0 0.0 0.0
7 1.0 3.0 1.0 1.0
8 0.0 0.0 0.0 1.0
9 1.0 0.0 3.0 2.0
print (z.apply(lambda x: x.where(x.isin(x.value_counts().head(n).index), 0)))
0 1 2 3
0 3 2 3 0
1 1 3 3 2
2 3 2 3 2
3 1 2 3 2
4 1 3 1 2
5 3 2 1 1
6 1 0 0 0
7 1 3 1 1
8 0 0 0 1
9 1 0 3 2
print (z.apply(lambda x: np.where(x.isin(x.value_counts().head(n).index), x, 0)))
0 1 2 3
0 3 2 3 0
1 1 3 3 2
2 3 2 3 2
3 1 2 3 2
4 1 3 1 2
5 3 2 1 1
6 1 0 0 0
7 1 3 1 1
8 0 0 0 1
9 1 0 3 2