我有一个Pandas数据框,其每一行都包含一个索引列表(一列名为“Indexes”,其中有一个逗号分隔的值字符串):
'索引'
'1,4,6,3,2,5,6,8'
'1,7,5,10,23,50'
我想使用apply来创建一个新矩阵(DataFrame?),其每一行在原始数据帧的相应行中列出的值上有1,在其他地方为0。假设我知道新列的数量,因为我有最小和最大索引(比如说0和10)。我可以使用iterrows / itertuples来构建一个新的矩阵,但有没有更有效的方法呢?我有一个1000万行的矩阵,但即使在100k这个很长一段时间。
[实施例]:
为便于理解,我将提供一个示例和所需的输出:
假设MAX_INDEX = 4且MIN_INDEX = 0:
输入:
'1,3,2,4-'
'0,1'
输出将是5列矩阵,有两行,如下所示:
0 1 1 1 1
1 1 0 0 0
[编辑] 问题仍然存在 - 虽然我发现它非常慢,只是因为我使用append创建了新的矩阵,而不是分配内存a-priori而只插入新行。所以一个解决方案是:
m=np.empty(shape=[df.shape[0],numFeatures])
i=0
for row in df.itertuples():
idxs = row[4] # column of peattributes
idxs = map(lambda(x):int(x),idxs.split(','))
r=np.zeros(numFeatures)
r[idxs] = 1
m[i,]=r
i+=1
感谢, 丹
答案 0 :(得分:0)
编辑:检查表示整数的字符串是否在原始字符串中要快得多(四次):
rng_str = [str(i) for i in range(MIN_INDEX, MAX_INDEX+1)]
s = df['Indexes'].apply(lambda row: [int(i in row) for i in rng_str])
pd.DataFrame(s.tolist())
注意:最后一步从一系列列表转换为数据帧。最后这样做比在apply
内更快。
以下原始答案:
我有一个解决方案,我很想知道它是否比你的速度更快。第一步是将字符串转换为list:
df['Indexes'] = df['Indexes'].apply(lambda s: [int(x) for x in s.split(',')])
然后我可以使用apply
函数逐行生成输出:
rng = range(MIN_INDEX, MAX_INDEX+1)
df.apply(lambda row: [int(i in row['Indexes']) for i in rng], axis=1)
输出:
0 [0, 1, 1, 1, 1]
1 [1, 1, 0, 0, 0]