适用与嵌套循环

时间:2018-09-03 05:56:53

标签: python pandas apply

我正在尝试在python中构建一个数据帧,该数据帧填充1和0,具体取决于一栏中的数字:

Date        Hour
2005-01-01  1
2005-01-01  2
2005-01-01  3
2005-01-01  4

我想根据“小时”中的数字创建新列,如果该行等于“小时”中的值,则为每列填充1,否则为0。

Date        Hour HE1 HE2 HE3 HE4
2005-01-01  1    1   0   0   0
2005-01-01  2    0   1   0   0
2005-01-01  3    0   0   1   0
2005-01-01  4    0   0   0   1

我可以使用以下代码来完成此操作,但是需要很长时间:

for x in range(1,5):
    _HE = 'HE' + str(x)
    for i in load.index:
        load.at[i, _HE] = 1 if load.at[i,'Hour']==x else 0

我觉得对于.apply()来说,这是一个很棒的应用程序(无双关语),但我无法使其正常工作。

您将如何加快速度?

3 个答案:

答案 0 :(得分:5)

不建议在熊猫循环中使用,因为如果存在某些矢量化解决方案,速度会很慢。

注意:函数apply中的循环也在内部进行。

因此,请使用pandas.get_dummiesDataFrame.add_prefixjoin添加到原始df

df = df.join(pd.get_dummies(df['Hour'].astype(str)).add_prefix('HE'))
print (df)
         Date  Hour  HE1  HE2  HE3  HE4
0  2005-01-01     1    1    0    0    0
1  2005-01-01     2    0    1    0    0
2  2005-01-01     3    0    0    1    0
3  2005-01-01     4    0    0    0    1

相似的功能具有不同的性能:

df = pd.concat([df] * 1000, ignore_index=True)

In [62]: %timeit df.join(pd.get_dummies(df['Hour'].astype(str)).add_prefix('HE'))
3.54 ms ± 277 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#U9-Forward solution
In [63]: %timeit df.join(df['Hour'].astype(str).str.get_dummies().add_prefix('HE'))
61.6 ms ± 297 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

答案 1 :(得分:3)

pandas.factorize和数组切片分配

j, h = pd.factorize(df.Hour)
i = np.arange(len(df))

b = np.zeros((len(df), len(h)), dtype=h.dtype)
b[i, j] = 1

df.join(pd.DataFrame(b, df.index, h).add_prefix('HE'))

         Date  Hour  HE1  HE2  HE3  HE4
0  2005-01-01     1    1    0    0    0
1  2005-01-01     2    0    1    0    0
2  2005-01-01     3    0    0    1    0
3  2005-01-01     4    0    0    0    1

答案 2 :(得分:0)

即使它与@jezrael的回答确实非常相似,但是,它也要好得多,(它只是将.str的访问器用于get_dummies

print(df.join(df['Hour'].astype(str).str.get_dummies().add_prefix('HE')))

输出:

         Date  Hour  HE1  HE2  HE3  HE4
0  2005-01-01     1    1    0    0    0
1  2005-01-01     2    0    1    0    0
2  2005-01-01     3    0    0    1    0
3  2005-01-01     4    0    0    0    1