Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 跨数据帧的行生成成对累积统计信息_Python_Scala_Apache Spark_Pyspark - Fatal编程技术网

Python 跨数据帧的行生成成对累积统计信息

Python 跨数据帧的行生成成对累积统计信息,python,scala,apache-spark,pyspark,Python,Scala,Apache Spark,Pyspark,我有一个包含3列的表:日期、id和键。我希望找到一种有效的方法,对一个id中的密钥的成对实例求和,然后与其他id中的总数合并。基本上是建立一个时间转换列表。例如: 输入: ╔══════════╦════╦═════╗ ║ Date ║ ID ║ Key ║ ╠══════════╬════╬═════╣ ║ 1/1/2018 ║ A ║ XY ║ ║ 1/2/2018 ║ A ║ GT ║ ║ 1/6/2018 ║ A ║ WE ║ ║ 1/9/2018 ║ A ║ PO

我有一个包含3列的表:日期、id和键。我希望找到一种有效的方法,对一个id中的密钥的成对实例求和,然后与其他id中的总数合并。基本上是建立一个时间转换列表。例如:

输入:

╔══════════╦════╦═════╗ ║ Date ║ ID ║ Key ║ ╠══════════╬════╬═════╣ ║ 1/1/2018 ║ A ║ XY ║ ║ 1/2/2018 ║ A ║ GT ║ ║ 1/6/2018 ║ A ║ WE ║ ║ 1/9/2018 ║ A ║ PO ║ ║ 1/2/2018 ║ B ║ XY ║ ║ 1/4/2018 ║ B ║ GT ║ ╚══════════╩════╩═════╝ ╔══════════╦════╦═════╗ ║ 日期║ 身份证件║ 钥匙║ ╠══════════╬════╬═════╣ ║ 1/1/2018 ║ A.║ XY║ ║ 1/2/2018 ║ A.║ 燃气轮机║ ║ 1/6/2018 ║ A.║ 我们║ ║ 1/9/2018 ║ A.║ 人事军官║ ║ 1/2/2018 ║ B║ XY║ ║ 1/4/2018 ║ B║ 燃气轮机║ ╚══════════╩════╩═════╝ 输出:

╔══════════╦═══════════╦═══════╗ ║ FirstKey ║ SecondKey ║ Count ║ ╠══════════╬═══════════╬═══════╣ ║ XY ║ GT ║ 2 ║ ║ GT ║ WE ║ 1 ║ ║ WE ║ PO ║ 1 ║ ╚══════════╩═══════════╩═══════╝ ╔══════════╦═══════════╦═══════╗ ║ 一键║ 第二键║ 计数║ ╠══════════╬═══════════╬═══════╣ ║ XY║ 燃气轮机║ 2.║ ║ 燃气轮机║ 我们║ 1.║ ║ 我们║ 人事军官║ 1.║ ╚══════════╩═══════════╩═══════╝ 按ID排序,然后按日期排序,然后循环并构建计数,这将非常简单,但我希望你们中的一位大师能够帮助我将其构建得更并行/高效

基本上,因为是按日期排序的,所以我试图捕获键之间的时间转换数。对于ID=A,我们有XY,然后我们有GT(所以增加XY->GT乘以1)。然后我们将GT后跟we(因此将GT->PO增加1)


使用scala/python处理spark。

这里有一个潜在的解决方案,只需要3行代码:

import pandas as pd

df = pd.DataFrame({'Date': ['1/1/2018', '1/2/2018', '1/6/2018', '1/9/2018', '1/2/2018', '1/4/2018'], 'ID': ['A', 'A', 'A', 'A', 'B', 'B'], 'Key': ['XY', 'GT', 'WE', 'PO', 'XY', 'GT']})
print(df)


       Date ID Key
0  1/1/2018  A  XY
1  1/2/2018  A  GT
2  1/6/2018  A  WE
3  1/9/2018  A  PO
4  1/2/2018  B  XY
5  1/4/2018  B  GT

这是一个可能的解决方案,只需要3行代码:

import pandas as pd

df = pd.DataFrame({'Date': ['1/1/2018', '1/2/2018', '1/6/2018', '1/9/2018', '1/2/2018', '1/4/2018'], 'ID': ['A', 'A', 'A', 'A', 'B', 'B'], 'Key': ['XY', 'GT', 'WE', 'PO', 'XY', 'GT']})
print(df)


       Date ID Key
0  1/1/2018  A  XY
1  1/2/2018  A  GT
2  1/6/2018  A  WE
3  1/9/2018  A  PO
4  1/2/2018  B  XY
5  1/4/2018  B  GT

下面是Scala中的一个解决方案,它使用
lag(Key,1)
将以前的/当前的密钥配对到密钥对计数:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
import spark.implicits._

val df = Seq(
  ("1/1/2018", "A", "XY"),
  ("1/2/2018", "A", "GT"),
  ("1/6/2018", "A", "WE"),
  ("1/9/2018", "A", "PO"),
  ("1/2/2018", "B", "XY"),
  ("1/4/2018", "B", "GT")
).toDF("Date", "ID", "Key")

val win = Window.partitionBy("ID").orderBy("Date", "Key")

df.
  withColumn("Date", to_date($"Date", "M/d/yyyy")).
  withColumn("FirstKey", lag($"Key", 1).over(win)).
  groupBy($"FirstKey", $"Key".as("SecondKey")).agg(count("*").as("Count")).
  where($"firstKey".isNotNull).
  show
// +--------+---------+-----+
// |FirstKey|SecondKey|Count|
// +--------+---------+-----+
// |      WE|       PO|    1|
// |      GT|       WE|    1|
// |      XY|       GT|    2|
// +--------+---------+-----+

请注意,到日期的
转换是为了确保正确的时间顺序。

这里是Scala中的一个解决方案,使用
延迟(键,1)
将以前/当前的键与键对计数配对:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
import spark.implicits._

val df = Seq(
  ("1/1/2018", "A", "XY"),
  ("1/2/2018", "A", "GT"),
  ("1/6/2018", "A", "WE"),
  ("1/9/2018", "A", "PO"),
  ("1/2/2018", "B", "XY"),
  ("1/4/2018", "B", "GT")
).toDF("Date", "ID", "Key")

val win = Window.partitionBy("ID").orderBy("Date", "Key")

df.
  withColumn("Date", to_date($"Date", "M/d/yyyy")).
  withColumn("FirstKey", lag($"Key", 1).over(win)).
  groupBy($"FirstKey", $"Key".as("SecondKey")).agg(count("*").as("Count")).
  where($"firstKey".isNotNull).
  show
// +--------+---------+-----+
// |FirstKey|SecondKey|Count|
// +--------+---------+-----+
// |      WE|       PO|    1|
// |      GT|       WE|    1|
// |      XY|       GT|    2|
// +--------+---------+-----+

请注意,
到日期的转换是为了确保正确的时间顺序。

您可以添加一个新列,显示由
日期
使用排序的每个
ID
的下一个
键。然后按
FirstKey
SecondKey
分组,然后:

从pyspark.sql导入窗口
从pyspark.sql.functions导入col,lead
df.withColumn(“第二个键”,lead(“键”)。结束(Window.partitionBy(“ID”)。orderBy(“日期”))\
.where(col(“SecondKey”).isNotNull())\
.groupBy(col(“Key”)。别名(“FirstKey”),“SecondKey”)\
.count()\
.show()
#+--------+---------+-----+
#|第一键|第二键|计数|
#+--------+---------+-----+
#|WE|PO|1|
#|GT |我们| 1|
#|XY | GT | 2|
#+--------+---------+-----+

这假定
Date
列是
DateType
,因此可以对其进行适当的排序。如果它是一个字符串,您将不得不这样做,否则排序将按字典顺序进行

您可以使用添加一个新列,显示按日期排序的每个
ID
的下一个
键。然后按
FirstKey
SecondKey
分组,然后:

从pyspark.sql导入窗口
从pyspark.sql.functions导入col,lead
df.withColumn(“第二个键”,lead(“键”)。结束(Window.partitionBy(“ID”)。orderBy(“日期”))\
.where(col(“SecondKey”).isNotNull())\
.groupBy(col(“Key”)。别名(“FirstKey”),“SecondKey”)\
.count()\
.show()
#+--------+---------+-----+
#|第一键|第二键|计数|
#+--------+---------+-----+
#|WE|PO|1|
#|GT |我们| 1|
#|XY | GT | 2|
#+--------+---------+-----+

这假定
Date
列是
DateType
,因此可以对其进行适当的排序。如果它是一个字符串,您将不得不这样做,否则排序将按字典顺序进行

为什么id=A只需要6种可能的组合中的3种?@VamsiPrabhala我不太明白?我本可以用更好的措辞。基本上,因为是按日期排序的,所以我试图捕获键之间的时间转换数。对于ID=A,我们有XY,然后我们有GT(所以增加XY->GT乘以1)。然后我们将GT后跟we(因此将GT->PO增加1)。这说明了吗?为什么id=A只需要6种可能的组合中的3种?@VamsiPrabhala我不确定我是否理解?我本可以用更好的措辞。基本上,因为是按日期排序的,所以我试图捕获键之间的时间转换数。对于ID=A,我们有XY,然后我们有GT(所以增加XY->GT乘以1)。然后我们将GT后跟we(因此将GT->PO增加1)。这说明了吗?这个循环似乎正是我所认为的“直接”解决方案。不幸的是,我认为这并不是真正意义上的平行,不是吗?你是对的。然而,我只是想到了一个办法。我将立即编辑我的答案。这个循环似乎正是我所认为的“直接”解决方案。不幸的是,我认为这并不是真正意义上的平行,不是吗?你是对的。然而,我只是想到了一个办法。我会马上修改我的答案。