考虑这样的Spark数据帧 df
+----+-------+----+----+
|bin|median|min|end|
+----+-------+----+----+
| 1| 0.0| 0| 0.5|
| 2| 1.0| 0.8| 1.7|
| 3| 2.0| 1.6| 2.5|
| 4| 4.0| 3.7| 4.7|
| 5| 6.0| 5.7| 6.3|
我想以 bin 为键,将每个属性/列作为单独的字典/列表拉出,意思是
median[1] = 0.0 #df[df.bin == 1]
median[key= 1,2,3,4,5] = [0.0,1.0,2.0,4.0,6.0]
min[key= 1,2,3,4,5] = [0,0.8,1.6,3.7,5.7]
我正在考虑类似映射到rdd的操作,如何进行更多的“数据帧”操作?有没有办法同时拉出所有列表?
median = {}
df.rdd.map(lambda row : median[row.bin] = row.median)
如果我想拉出列表而不是字典,答案是什么?假设bin将从1开始连续编号?我们如何确保保持订单状态? .orderBy().collect()
吗?
答案 0 :(得分:1)
如果您仍然尝试collect
数据,则IMO以最理想的格式获取所需格式的数据就是通过熊猫。
您可以调用toPandas()
,将索引设置为bin
,然后调用to_dict()
:
output = df.toPandas().set_index("bin").to_dict()
print(output)
#{'end': {1: 0.5, 2: 1.7, 3: 2.5, 4: 4.7, 5: 6.3},
# 'median': {1: 0.0, 2: 1.0, 3: 2.0, 4: 4.0, 5: 6.0},
# 'min': {1: 0.0, 2: 0.8, 3: 1.6, 4: 3.7, 5: 5.7}}
这将创建一个词典字典,其中外键是列名,内键是bin。如果您想使用单独的变量,则可以从output
中提取出来,但是不要使用min
作为变量名,因为它会踩在__builtin__.min
上。
median, min_, end = output['median'], output['min'], output['end']
print(median[1])
#0.0
答案 1 :(得分:1)
这是另一种为键和列过滤提供支持的方法。该解决方案包含两个功能:
as_dict(df, cols, ids, key)
:将数据返回到字典中extract_col_from_dict(dct, col, ids)
:从字典中提取列数据首先,让我们从给定的数据帧中将所需数据提取到字典中:
def as_dict(df, cols = [], ids = [], key = 0):
key_idx = 0
if isinstance(key, int):
key_idx = key
key = df.columns[key_idx]
elif isinstance(key, str):
key_idx = df.columns.index(key)
else:
raise Exception("Please provide a valid key e.g:{1, 'col1'}")
df = df.select("*") if not cols else df.select(*[[key] + cols])
if ids:
df = df.where(df[key].isin(ids))
return df.rdd.map(lambda x : (x[key_idx], x.asDict())).collectAsMap()
参数:
让我们用您的数据集调用函数:
df = spark.createDataFrame(
[(1, 0.0, 0., 0.5),
(2, 1.0, 0.8, 1.7),
(3, 2.0, 1.6, 2.5),
(4, 4.0, 3.7, 4.7),
(5, 6.0, 5.7, 6.3)], ["bin", "median", "min", "end"])
dict_ = as_dict(df)
dict_
{1: {'bin': 1, 'min': 0.0, 'end': 0.5, 'median': 0.0},
2: {'bin': 2, 'min': 0.8, 'end': 1.7, 'median': 1.0},
3: {'bin': 3, 'min': 1.6, 'end': 2.5, 'median': 2.0},
4: {'bin': 4, 'min': 3.7, 'end': 4.7, 'median': 4.0},
5: {'bin': 5, 'min': 5.7, 'end': 6.3, 'median': 6.0}}
# or with filters applied
dict_ = as_dict(df, cols = ['min', 'end'], ids = [1, 2, 3])
dict_
{1: {'bin': 1, 'min': 0.0, 'end': 0.5},
2: {'bin': 2, 'min': 0.8, 'end': 1.7},
3: {'bin': 3, 'min': 1.6, 'end': 2.5}}
该函数会将记录映射到键/值对,其中值也将是字典(调用row.asDict)。
调用as_dict函数后,数据将位于驱动程序上,现在您可以使用extract_col_from_dict提取所需的数据:
def extract_col_from_dict(dct, col, ids = []):
filtered = {}
if ids:
filtered = { key:val for key, val in dct.items() if key in ids }
else:
filtered = { key:val for key, val in dct.items() }
return [d[col] for d in list(filtered.values())]
参数:
函数的输出:
min_data = extract_col_from_dict(dict_, 'min')
min_data
[0.0, 0.8, 1.6, 3.7, 5.7]