Mengekstraksi tahun dari Tanggal dalam kerangka data Pyspark

Saya memiliki bingkai data Pyspark yang berisi kolom tanggal "Tanggal Dilaporkan" (tipe: string). Saya ingin menghitung kolom lain setelah mengekstraksi tahun dari tanggal.

Saya bisa menghitungnya jika saya menggunakan kolom tanggal string.

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

dan saya mendapatkan hasil ini

+-------------+------------------+
|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|
+-------------+------------------+

Untuk mengekstrak tahun dari "Tanggal Dilaporkan" saya telah mengonversinya ke format tanggal (menggunakan pendekatan ini) dan memberi nama kolom "Tanggal". Namun, ketika saya mencoba menggunakan kode yang sama untuk mengelompokkan berdasarkan kolom baru dan menghitung, saya mendapatkan pesan kesalahan.

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

Ini adalah skema datanya:

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

Apakah ada cara untuk memperbaiki kesalahan ini? atau mengekstrak tahunnya menggunakan metode lain? Terima kasih


person leena    schedule 24.08.2019    source sumber


Jawaban (1)


Jika saya mengerti dengan benar maka Anda ingin mengekstrak tahun dari kolom tanggal String. Tentu saja, salah satu caranya adalah dengan menggunakan regex tetapi terkadang hal ini dapat mengganggu logika Anda jika regex tidak menangani semua skenario.

berikut adalah pendekatan tipe data tanggal.

Impor

import pyspark.sql.functions as f

Membuat Kerangka Data Anda

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|
+----------+---+

Sekarang, Anda dapat menggunakan paket fungsi to_timestamp atau 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|
+----------+---+-----+

Sekarang, kelompokkan berdasarkan tahun.

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

Ditampilkan dalam beberapa langkah untuk pemahaman tetapi Anda dapat menggabungkan tahun ekstrak dan mengelompokkannya dalam satu langkah.

Senang untuk menyampaikan jika Anda membutuhkan bantuan lain.

person SMaZ    schedule 25.08.2019
comment
Terima kasih atas jawaban Anda SMaZ. Saya menerapkannya ke DataFrame saya dan mengembalikan hasil yang mirip dengan Anda. Masalahnya sekarang adalah keluarannya menunjukkan tahun duplikat? Saya tidak mendapatkan jumlah per tahun. Yang merupakan tujuan utama dari kode ini. - person leena; 25.08.2019
comment
Apakah Anda ingin mempertahankan kolom tanggal asli Anda? atau hanya jumlah pada tahun itu? - person SMaZ; 25.08.2019
comment
Bagus, Senang bisa membantu. Jawabannya baru saja diedit juga. Selamat coding..! - person SMaZ; 25.08.2019