我有这样的df:
cols=['a', 'b']
df = pd.DataFrame([[[3,1,5,7], [42,31]], [[],[44]], [[44,3,5,5,5,10],[]], [[], [44324,3]]],
columns=cols)就像你看到的每个牢房里都有名单。我想关注每一个元素的内容:
。
我的工作解决方案:
df
def convert_list(x):
if len(x) != 0:
res = (sum(x)/len(x)) + 5
if res <= 0:
res = 1
return res
return 0
for col in cols:
df[col] = df[col].apply(lambda x: convert_list(x))期望产出:
df它正在工作,但它的解决方案非常慢(在最初的df中,我得到了大约50k列和100 k行,列表可能包含许多元素)。有什么有效的解决办法吗?我还尝试将其转换为numpy数组并执行一些向量化操作,但问题是每个列表都可能有不同的长度,所以我无法转换它(除非我向其他列表中添加了许多元素.)
发布于 2021-11-17 14:09:00
您可以使用applymap和np.mean对每个单元格进行平均,并添加5。那么低于5的任何值都是负数,can可以填充为零。
import pandas as pd
import numpy as np
cols=['a', 'b']
df = pd.DataFrame([[[3,1,5,7], [42,31]], [[],[44]], [[44,3,5,5,5,10],[]], [[], [44324,3]]],
columns=cols)
df = (df.applymap(np.mean)+5)
df[df<5]=1
df = df.fillna(0)输出
a b
0 9.0 41.5
1 0.0 49.0
2 17.0 0.0
3 0.0 22168.5发布于 2021-11-17 14:27:19
您可以尝试使用explode,然后使用聚合,并避免使用apply。
差不多,但它很丑。
def correct_column(col):
cole = col.explode()
m_empty = cole.isna().groupby(cole.index).first()
groups = cole.groupby(cole.index)
col_sum = groups.sum()
col_count = groups.count()
col = groups.sum() / groups.count() + 5
m_negative = col <= 0
col[m_empty] = 0
col[m_negative] = 1
return col
for col in df.columns:
df[col] = correct_column(df[col])注意:groups.sum() / groups.count()可能是获取平均值的奇怪方法,但对于空列表(NaN之后的explode),当sum返回0时,mean会引发错误。
https://stackoverflow.com/questions/70005428
复制相似问题