如何对一行使用groupby



我想对一行进行分组:

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

最新更新