熊猫迭代到Pyspark函数

时间:2020-04-21 12:31:26

标签: python pandas pyspark

给出一个数据集,我试图创建一个逻辑,在该逻辑中,我需要在两个列中强制执行连续性,即最后一个目的地(到列)是每个id的确切下一个起点(从列开始)。例如此表

+----+-------+-------+
| id | from  | to    |
+----+-------+-------+
|  1 | A     | B     |
|  1 | C     | A     |
|  2 | D     | D     |
|  2 | F     | G     |
|  2 | F     | F     |
+----+-------+-------+

理想情况下应如下所示:

+----+-------+-------+
| id | from  | to    |
+----+-------+-------+
|  1 | A     | B     |
|  1 | B     | C     |
|  1 | C     | A     |
|  2 | D     | D     |
|  2 | D     | F     |
|  2 | F     | G     |
|  2 | G     | F     |
|  2 | F     | F     |
+----+-------+-------+

使用大熊猫,是通过逐行循环并检查是否previous_row ['to'] == current_row ['from']来实现的,这也是使用groupby可以避免的id的检查,如您在下面看到的那样< / p>

for i in range(len(df)):
    if (i < (len(df)-1)):
        if (new.ix[i,"to"] != new.ix[i+1,"from"]) & (new.ix[i,"id"] == new.ix[i+1,"id"]): 
            new_index = i + 0.5
            line = pd.DataFrame({"id":new.ix[i,"id"],
                             "from":new.ix[i,"to"],"to":new.ix[i+1,"from"],}, index = [new_index])
            appendings = pd.concat([appendings,line])
        else:
            pass
    else:
        pass

是否可以将其“翻译”为pyspark rdds?

我知道,在Pyspark中复制远非循环和if-else逻辑远非最佳。

我考虑了按列分组和在列之间来回压缩,并在单个列上工作。这样做的主要问题在于我可以在“错误”的行上产生一个标志,但是如果不使用按索引操作就无法插入新行。

1 个答案:

答案 0 :(得分:0)

这不是pyspark的答案,而是部分答案,向您展示如何在 pandas 中无循环地完成任务。

您可以尝试:

def f(sub_df):
    return sub_df.assign(to_=np.roll(sub_df.To, 1)) \
                .apply(lambda x: [[x.From, x.To]] if x.to_ == x.From else [[x.to_, x.From], [x.From, x.To]], axis=1) \
                .explode() \
                .apply(pd.Series)


out = df.groupby('id').apply(f) \
        .reset_index(level=1, drop=True) \
        .rename(columns={0: "from", 1: "to"})

工作流程:

  • 使用groupby通过id对数据框进行分组
  • 对于每个组:
    • 创建新列(此处为to_)以具有上一行。 np.roll执行循环移位以保持最后一个值。
    • 根据当前 == 之前的:返回当前行或添加新行以进行过渡。
    • 使用explodelist的{​​{1}}分解为每行一个列表。
    • 使用apply(pd.Series)
    • 将列转换为两列
  • 然后,对于输出数据帧,使用reset_index
  • 删除 level 1 索引
  • 然后使用rename
  • 重命名列

完整代码

list

下一步是将其转换为# Import module import pandas as pd import numpy as np # create dataset df = pd.DataFrame({"id": [1,1,2,2,2], "From": ["A", "C", "D", "F", "F"], "To": ["B", "D", "D", "G", "F"]}) # print(df) def f(sub_df): return sub_df.assign(to_=np.roll(sub_df.To, 1)) \ .apply(lambda x: [[x.From, x.To]] if x.to_ == x.From else [[x.to_, x.From], [x.From, x.To]], axis=1) \ .explode() \ .apply(pd.Series) out = df.groupby('id').apply(f) \ .reset_index(level=1, drop=True) \ .rename(columns={0: "from", 1: "to"}) print(out) # from to # id # 1 D A # 1 A B # 1 B C # 1 C D # 2 F D # 2 D D # 2 D F # 2 F G # 2 G F # 2 F F 。尝试一下,随时尝试尝试提出一个新问题。

相关问题