【发布时间】:2023-04-07 05:56:01
【问题描述】:
我正在尝试处理数据框。这包括创建新列并根据其他列中的值更新它们的值。更具体地说,我有一个要分类的预定义“来源”。该来源可以属于三个不同的类别“source_dtp”、“source_dtot”和“source_cash”。我想根据原始“源”列向数据框中添加三个新列,这些列由 1 或 0 组成。
我目前能够做到这一点,只是真的很慢...
原始列示例:
source
_id
AV4MdG6Ihowv-SKBN_nB DTP
AV4Mc2vNhowv-SKBN_Rn Cash 1
AV4MeisikOpWpLdepWy6 DTP
AV4MeRh6howv-SKBOBOn Cash 1
AV4Mezwchowv-SKBOB_S DTOT
AV4MeB7yhowv-SKBOA5b DTP
期望的输出:
source_dtp source_dtot source_cash
_id
AV4MdG6Ihowv-SKBN_nB 1.0 0.0 0.0
AV4Mc2vNhowv-SKBN_Rn 0.0 0.0 1.0
AV4MeisikOpWpLdepWy6 1.0 0.0 0.0
AV4MeRh6howv-SKBOBOn 0.0 0.0 1.0
AV4Mezwchowv-SKBOB_S 0.0 1.0 0.0
AV4MeB7yhowv-SKBOA5b 1.0 0.0 0.0
这是我目前的方法,但速度很慢。我更喜欢这样做的矢量化形式,但我不知道如何 - 因为条件非常复杂。
# For 'source' we will use the following classes:
source_cats = ['source_dtp', 'source_dtot', 'source_cash']
# [0, 0, 0] would imply 'other', hence no need for a fourth category
# add new features to dataframe, initializing to nan
for cat in source_cats:
data[cat] = np.nan
for row in data.itertuples():
# create series to hold the result per row e.g. [1, 0, 0] for `cash`
cat = [0, 0, 0]
index = row[0]
# to string as some entries are numerical
source_type = str(data.loc[index, 'source']).lower()
if 'dtp' in source_type:
cat[0] = 1
if 'dtot' in source_type:
cat[1] = 1
if 'cash' in source_type:
cat[2] = 1
data.loc[index, source_cats] = cat
我正在使用 itertuples(),因为它被证明比 interrows() 更快。
有没有一种更快的方法来实现与上述相同的功能?
编辑:这不仅仅是关于创建一个热编码。它归结为根据另一列的值更新列值。例如。如果我有某个location_id,我想更新其各自的longitude 和latitude 列-基于该原始ID(不以我上面的方式进行迭代,因为它对于大型数据集来说真的很慢)。
【问题讨论】:
-
df.source.str.get_dummies()将为您提供 0 和 1。然后,使用pd.concat加入您的数据框,或者直接调用df.assign。 -
是的,您可以使用 np.where 或 np.select 执行此操作。如果您提出了一个具有良好样本数据和预期结果的更好问题,我们 Stack Overflow 社区将向您展示如何做。
-
正如@ScottBoston 所说,从一开始就提到这一点会很有帮助。您编写所有这些代码来演示 MCVE 的事实使我们相信它反映了您的实际用例。现在,您需要提供更多数据和预期输出,以便我们了解您的实际用例以及它与这个用例有何不同。
-
@vconvo 如果您的问题得到了here 的回答,请也关闭此问题,并接受我们的答案之一。
-
@coldspeed @Scott Boston 我会提出另一个问题——我没想到会有针对上述问题的特定解决方案 (
get_dummies())
标签: python pandas dataframe data-processing