我想对一行进行分组:
col1 col2 col3 col4 col5
'A' 'B' 'B' 'A' 'B'
2 4 3 2 1
0 1 2 4 0
1 1 1 1 1
如果两列在第一行中具有相同的值,我想过滤这个数据帧,并将它们的平均值放进去。
例如,第一列和第四列在第一行中具有相同的值"A",并且这些行的平均值为:
first row: (2+2)/2=2
second row: (0+4)/2=2
third row: (1+1)/2=1
对于具有值CCD_ 1的列也是如此。所以输出是
col1 col2
'A' 'B'
2 7/3
2 3/3
1 3/3
正如我在评论中提到的,将字符串和整数混合在一列中并不实用。最好将字母行作为列名的一部分,或者将此数据帧转换为将字母行用作列。
我将展示如何将字母行作为列名的一部分,并从中获得平均值。
df = spark.createDataFrame([
['A', 'B', 'B', 'A', 'B'],
['2', '4', '3', '2', '1'],
['0', '1', '2', '4', '0'],
['1', '1', '1', '1', '1']
], ['col1', 'col2', 'col3', 'col4', 'col5'])
letter_row = df.filter(df.col1.rlike('[^d]')).take(1)[0]
new_cols = [f'{letter_row[x]}_{x}' for x in letter_row.asDict()]
df = df.filter(df.col1.rlike('d+')).toDF(*new_cols)
# df.show()
# +------+------+------+------+------+
# |A_col1|B_col2|B_col3|A_col4|B_col5|
# +------+------+------+------+------+
# | 2| 4| 3| 2| 1|
# | 0| 1| 2| 4| 0|
# | 1| 1| 1| 1| 1|
# +------+------+------+------+------+
acols = [x for x in df.columns if x.startswith('A_')]
bcols = [x for x in df.columns if x.startswith('B_')]
df = (df.withColumn('A_avg', sum(F.col(x) for x in acols) / len(acols))
.withColumn('B_avg', sum(F.col(x) for x in bcols) / len(bcols)))
结果
+------+------+------+------+------+-----+-----+
|A_col1|B_col2|B_col3|A_col4|B_col5|A_avg|B_avg|
+------+------+------+------+------+-----+-----+
| 2| 4| 3| 2| 1| 2.0| 2.66|
| 0| 1| 2| 4| 0| 2.0| 1.0|
| 1| 1| 1| 1| 1| 1.0| 1.0|
+------+------+------+------+------+-----+-----+