แยกปีจาก Date ใน Pyspark dataframe

ฉันมีกรอบข้อมูล Pyspark ที่มีคอลัมน์วันที่ "วันที่รายงาน" (ประเภท: สตริง) ฉันต้องการนับจำนวนคอลัมน์อื่นหลังจากแยกปีออกจากวันที่

ฉันสามารถรับการนับได้หากฉันใช้คอลัมน์วันที่ของสตริง

crimeFile_date.groupBy("Reported Date").sum("Offence Count").show()

และฉันได้ผลลัพธ์นี้

+-------------+------------------+
|Reported Date|sum(Offence Count)|
+-------------+------------------+
|   13/08/2010|               342|
|    6/10/2011|               334|
|   27/11/2011|               269|
|   12/01/2012|               303|
|   22/02/2012|               286|
|   31/07/2012|               276|
|   25/04/2013|               222|
+-------------+------------------+

หากต้องการแยกปีจาก "วันที่รายงาน" ฉันได้แปลงเป็นรูปแบบวันที่ (ใช้แนวทางนี้) และตั้งชื่อคอลัมน์ว่า "วันที่" อย่างไรก็ตาม เมื่อฉันพยายามใช้โค้ดเดียวกันเพื่อจัดกลุ่มตามคอลัมน์ใหม่และนับ ฉันได้รับข้อความแสดงข้อผิดพลาด

crimeFile_date.groupBy(year("Date").alias("year")).sum("Offence Count").show()
TypeError: strptime() argument 1 must be str, not None

นี่คือสคีมาข้อมูล:

root
 |-- Offence Count: integer (nullable = true)
 |-- Reported Date: string (nullable = true)
 |-- Date: date (nullable = true)

มีวิธีแก้ไขข้อผิดพลาดนี้หรือไม่? หรือแยกปีด้วยวิธีอื่น? ขอบคุณ


person leena    schedule 24.08.2019    source แหล่งที่มา


คำตอบ (1)


ถ้าฉันเข้าใจถูกต้องคุณต้องการแยกปีออกจากคอลัมน์วันที่ของสตริง แน่นอนว่าวิธีหนึ่งคือการใช้ regex แต่บางครั้งก็อาจทำให้ตรรกะของคุณพังได้หาก regex ไม่ได้จัดการทุกสถานการณ์

นี่คือวิธีการประเภทข้อมูลวันที่

นำเข้า

import pyspark.sql.functions as f

การสร้าง Dataframe ของคุณ

l1 = [('13/08/2010',342),('6/10/2011',334),('27/11/2011',269),('12/01/2012',303),('22/02/2012',286),('31/07/2012',276),('25/04/2013',222)]
dfl1 =  spark.createDataFrame(l1).toDF("dates","sum")

dfl1.show()
+----------+---+
|     dates|sum|
+----------+---+
|13/08/2010|342|
| 6/10/2011|334|
|27/11/2011|269|
|12/01/2012|303|
|22/02/2012|286|
|31/07/2012|276|
|25/04/2013|222|
+----------+---+

ตอนนี้คุณสามารถใช้ to_timestamp หรือ to_date apis ของแพ็คเกจฟังก์ชั่นได้

dfl2 = dfl1.withColumn('years',f.year(f.to_timestamp('dates', 'dd/MM/yyyy')))

dfl2.show()
+----------+---+-----+
|     dates|sum|years|
+----------+---+-----+
|13/08/2010|342| 2010|
| 6/10/2011|334| 2011|
|27/11/2011|269| 2011|
|12/01/2012|303| 2012|
|22/02/2012|286| 2012|
|31/07/2012|276| 2012|
|25/04/2013|222| 2013|
+----------+---+-----+

ตอนนี้จัดกลุ่มตามปี

dfl2.groupBy('years').sum('sum').show()
+-----+--------+                                                                
|years|sum(sum)|
+-----+--------+
| 2013|     222|
| 2012|     865|
| 2010|     342|
| 2011|     603|
+-----+--------+

แสดงเป็นหลายขั้นตอนเพื่อทำความเข้าใจ แต่คุณสามารถรวมปีและกลุ่มแยกได้ในขั้นตอนเดียว

ยินดีที่จะขยายเวลาหากคุณต้องการความช่วยเหลืออื่น ๆ

person SMaZ    schedule 25.08.2019
comment
ขอบคุณสำหรับคำตอบครับคุณ SMaZ ฉันนำไปใช้กับ DataFrame ของฉัน และผลลัพธ์ก็กลับมาคล้ายกับของคุณ ปัญหาตอนนี้คือผลลัพธ์แสดงปีที่ซ้ำกันใช่ไหม ฉันไม่ได้รับเงินต่อปี ซึ่งเป็นเป้าหมายหลักของโค้ดนี้ - person leena; 25.08.2019
comment
คุณต้องการเก็บคอลัมน์วันที่เดิมไว้หรือไม่ หรือเพียงแค่ผลรวมของปี? - person SMaZ; 25.08.2019
comment
เยี่ยมเลย ดีใจที่สามารถช่วยได้ เพิ่งแก้ไขคำตอบด้วย ขอให้มีความสุขในการเขียนโค้ด..! - person SMaZ; 25.08.2019