Python/Pyspark-如何用平均值替换某些单元格?

Python/Pyspark-如何用平均值替换某些单元格?,python,pyspark,spark-dataframe,pyspark-sql,Python,Pyspark,Spark Dataframe,Pyspark Sql,我有一个很大的问题,我希望有人能帮我。 我想用另一个值替换列中的单元格 数据帧看起来像: ---------------------------------------- |Timestamp | Item_ID | Price | ---------------------------------------- |2017-05-01 11:05:00 | 12345 | 70 | |2017-05-01 17:20:00 | 98765 | 10 |

我有一个很大的问题,我希望有人能帮我。 我想用另一个值替换列中的单元格

数据帧看起来像:

----------------------------------------
|Timestamp           | Item_ID | Price |
----------------------------------------
|2017-05-01 11:05:00 | 12345   | 70    |
|2017-05-01 17:20:00 | 98765   | 10    |
|2017-05-01 11:50:00 | 12345   | 20    |
|2017-05-01 19:50:00 | 12345   | 0     |
|2017-05-01 20:17:00 | 12345   | 0     |
|2017-05-01 22:01:00 | 98765   | 0     |
----------------------------------------
正如你所看到的,随着时间的推移,相同的商品会有不同的价格。 例如,“12345”项有三种价格:70、20和0 现在我想用其他价格的平均值替换所有“0”。 这样的事情可能吗

结果应该是: 对于项目12345:(70+20)/2=45 对于98765项:只有一个价格,所以接受这个

----------------------------------------
|Timestamp           | Item_ID | Price |
----------------------------------------
|2017-05-01 11:05:00 | 12345   | 70    |
|2017-05-01 17:20:00 | 98765   | 10    |
|2017-05-01 11:50:00 | 12345   | 20    |
|2017-05-01 19:50:00 | 12345   | 45    |
|2017-05-01 20:17:00 | 12345   | 45    |
|2017-05-01 22:01:00 | 98765   | 10    |
----------------------------------------
非常感谢你,祝你今天愉快!
qwertz

这里有一种使用sparkSQL的方法:

from StringIO import StringIO
import pandas as pd

# create dummy data
df = pd.DataFrame.from_csv(StringIO("""Timestamp|Item_ID|Price
2017-05-01 11:05:00|12345|70    
2017-05-01 17:20:00|98765|10    
2017-05-01 11:50:00|12345|20    
2017-05-01 19:50:00|12345|0     
2017-05-01 20:17:00|12345|0     
2017-05-01 22:01:00|98765|0""".replace("\s+", '')), sep="|").reset_index()

df['Timestamp'] = df['Timestamp'].astype(str)
spark_df = sqlCtx.createDataFrame(df)

spark_df.registerTempTable('table')
sqlCtx.sql("""SELECT Timestamp,
    l.Item_ID,
    CASE WHEN l.Price > 0 THEN l.Price ELSE r.Price END AS Price
    FROM table l 
    LEFT JOIN (
        SELECT Item_ID,
        AVG(Price) AS Price
        FROM table
        WHERE Price > 0
        GROUP BY Item_ID
    ) r ON l.Item_ID = r.Item_ID""".replace("\n", ' ')
).show()
输出:

+-------------------+-------+-----+
|Timestamp          |Item_ID|Price|
+-------------------+-------+-----+
|2017-05-01 19:50:00|12345  |45.0 |
|2017-05-01 20:17:00|12345  |45.0 |
|2017-05-01 11:05:00|12345  |70.0 |
|2017-05-01 11:50:00|12345  |20.0 |
|2017-05-01 17:20:00|98765  |10.0 |
|2017-05-01 22:01:00|98765  |10.0 |
+-------------------+-------+-----+
说明

通过调用
spark\u df.registerTempTable('table')
,我将
spark数据帧注册为
SQLContext
中的一个临时表(我将其命名为
table
)。我正在运行的查询是使用
Item\u ID
连接到自身,但其中一方将具有聚合(平均)值。然后我使用
CASE
语句选择给定值,或者如果
Price
0
则选择聚合值

我调用了
.replace(“\n”,”)
,因为不支持换行符(我认为它们被视为
EOF
)。这是一种编写可读查询的简单方法,无需将所有内容放在一行中

注释

你所描述的技术是均值插补。由于这在该领域非常常见,我不得不相信有另一种(可能更好)方法可以做到这一点,只使用
spark DataFrame
函数(避免
SQL