以最节省时间和内存的方式操作 Pandas 数据帧

问题描述 投票:0回答:1

请想象我有一个像这样的数据框:

df = pd.DataFrame(index=pd.Index(['1', '1', '2', '2'], name='from'), columns=['to'], data= ['2', '2', '4', '5'])

df:

enter image description here

现在,我想计算一个矩阵,其中包含索引“from”中每个值转换到“to”列中每个值的次数百分比,这称为转换矩阵。我可以通过首先创建一个空的转换矩阵,然后使用 for 循环用百分比填充它来实现这一点:

#Create an empty matrix to populate later (using sparse dtype to save memory):
matrix = pd.DataFrame(index=df.index.unique(), columns=df.to.unique(), data=0, dtype=pd.SparseDtype(dtype=np.float16, fill_value=0)) 

矩阵:

enter image description here

for i in range(len(df)):
    from_, to = df.index[i], df.to.iloc[i]     
    matrix[to] = matrix[to].sparse.to_dense() # Convert to dense format because sparse dtype does not allow value assignment with .loc in the next line:  
    matrix.loc[from_, to] += 1     # Do a normal insertion with .loc[]
    matrix[to] = matrix[to].astype(pd.SparseDtype(dtype=np.float16, fill_value=0)) # Back to the original sparse format

matrix = (matrix.div(matrix.sum(axis=1), axis=0)*100) # converting counts to percentages

矩阵:

enter image description here

这有效。例如,索引“1”仅转换为“2”(100% 的时间),索引“2”50% 的时间转换为“4”,其余 50% 的时间转换为“5”,如下所示:在

df.

进行验证

问题:实际矩阵约为 500K x 500K,for 循环需要很长时间才能完成。那么,是否有一种矢量化或其他有效的方法从

matrix
 计算 
df

注意:即使在

dtype=float16
中使用
pd.DataFrame()
,我也会在不使用整个 Sparse dtype 的情况下得到 MemoryError,所以如果可能的话,我更愿意保留它。另外,如果重要的话,显然这些百分比总是有 0-100 的范围。

python pandas dataframe numpy vectorization
1个回答
0
投票

这是一种方法:

out = (pd.crosstab(index=df.index, 
                   columns=df['to'], 
                   normalize='index'
                   )
       .mul(100)
       .rename_axis(index='from', columns=None)
       )

输出:

          2     4     5
from                   
1     100.0   0.0   0.0
2       0.0  50.0  50.0
© www.soinside.com 2019 - 2024. All rights reserved.