![](/img/trans.png)
[英]Extracting value of specific cell and populating it in place of NA values in pyspark dataframe
[英]Assign value to specific cell in PySpark dataFrame
我想使用PySpark
更改我的Spark DataFrame
的特定單元格中的值。
簡單的例子——我創建了一個模擬Spark DataFrame
:
df = spark.createDataFrame(
[
(1, 1.87, 'new_york'),
(4, 2.76, 'la'),
(6, 3.3, 'boston'),
(8, 4.1, 'detroit'),
(2, 5.70, 'miami'),
(3, 6.320, 'atlanta'),
(1, 6.1, 'houston')
],
('variable_1', "variable_2", "variable_3")
)
Runnning display(df)
我得到這張表:
variable_1 variable_2 variable_3
1 1.87 new_york
4 2.76 la
6 3.3 boston
8 4.1 detroit
2 5.7 miami
3 6.32 atlanta
1 6.1 houston
比方說,我想為第 4 行和第 3 列中的單元格分配一個新值,即將detroit
更改為new_orleans
。 我知道df.iloc[4, 3] = 'new_orleans'
或df.loc[4, 'detroit'] = 'new_orleans'
在Spark
中無效。
使用when
對我的問題的有效答案是:
from pyspark.sql.functions import when
targetDf = df.withColumn("variable_3", \
when(((df["variable_1"] == 8) & (df["variable_2"] == 4.1)) , 'new_orleans').otherwise(df["variable_3"]))
我的問題是:這是否可以在PySpark
中以更實用的方式完成,而無需輸入我只想更改 1 個單元格的行的所有值和列名(可能在不使用when
函數的情況下實現相同)?
預先感謝您的幫助和@useruser9806664 的反饋。
Spark DataFrames
是不可變的 , 不提供隨機訪問 ,嚴格來說,它是無序的 。 結果是:
您可以做的是使用新的列創建一個新的數據框,使用一些條件表達式替換現有的數據框,該條件表達式已包含在您找到的答案中。
另外, monotonically_increasing_id
不會添加索引(行號)。 它添加單調遞增的數字,不一定是連續的數字或從任何特定值開始(如果是空分區)。
Spark DataFrame 確實是不可變的,因此,它們不是為修改而設計的。 Spark Dataframes 是分布式數據 collections 針對處理大量數據進行了優化,如果您想進行任何更改,則必須創建一個包含所需修改的新數據框。
然而,有時您可能需要修改特定行的特定單元格。 對於這些情況,您可以使用when function(就像您在示例中所做的那樣)使用與您要修改的特定單元格位於同一行的單元格值來修改該列。 或者您可以考慮將您的 Spark Dataframe 轉換為 Pandas DataFrame (它們是可變的),並在將新值分配給相關單元格后,將其轉換回 Spark DataFrame 。 這是您可以如何做到的:
# Copy the schema of your Spark dataframe
schema = df.schema
# Create Pandas Dataframe using your Spark DataFrame
pandas_df = df.toPandas()
# Assign the new value to the specific cell (you could use .at or .loc)
pandas_df.at[3, 'variable_3'] = 'new_orleans'
# Update your dataframe with the new value using the Pandas DataFrame
df = spark.createDataFrame(pandas_df,schema=schema)
# Delete the auxiliary pandas dataframe to free memory for other uses
del pandas_df
請記住,Pandas DataFrames 不是分布式的,在 Pandas DataFrame 處理大量數據會更慢。
您可以使用基礎的RDD創建行號:
from pyspark.sql import Row
# Function to update dataframe row with a rownumber
def create_rownum(ziprow):
row, index=ziprow
row=row.asDict()
row['rownum']= index
return(Row(**row))
# First create a rownumber then add to dataframe
df.rdd.zipWithIndex().map(create_rownum).toDF().show()
現在,您可以過濾DataFrame以獲得所需的行號。
我遇到了同樣的問題,但我使用了 sql 表達式:
expr = """CASE WHEN variable1==8 AND variable==4.1 THEN 'new_orleans' ELSE variable3 END AS variable4"""
df = df.selectExpr(*,expr)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.