I need to transform a DataFrame in which one of the columns consists of a list of tuples, each item in each of the tuples has to be a separate column.
Here is an example and a solution in Pandas:
import pandas as pd
df_dict = {
'a': {
"1": "stuff", "2": "stuff2"
},
"d": {
"1": [(1, 2), (3, 4)], "2": [(1, 2), (3, 4)]
}
}
df = pd.DataFrame.from_dict(df_dict)
print(df) # intial structure
a d
1 stuff [(1, 2), (3, 4)]
2 stuff2 [(1, 2), (3, 4)]
# first transformation, let's separate each list item into a new row
row_breakdown = df.set_index(["a"])["d"].apply(pd.Series).stack()
print(row_breakdown)
a
stuff 0 (1, 2)
1 (3, 4)
stuff2 0 (1, 2)
1 (3, 4)
dtype: object
row_breakdown = row_breakdown.reset_index().drop(columns=["level_1"])
print(row_breakdown)
a 0
0 stuff (1, 2)
1 stuff (3, 4)
2 stuff2 (1, 2)
3 stuff2 (3, 4)
# second transformation, let's get each tuple item into a separate column
row_breakdown.columns = ["a", "d"]
row_breakdown = row_breakdown["d"].apply(pd.Series)
row_breakdown.columns = ["value_1", "value_2"]
print(row_breakdown)
value_1 value_2
0 1 2
1 3 4
2 1 2
3 3 4
This is the pandas solution. I need to be able to do the same but using PySpark (2.3). I have started working on it, but immediately got stuck:
from pyspark.context import SparkContext, SparkConf
from pyspark.sql.session import SparkSession
conf = SparkConf().setAppName("appName").setMaster("local")
sc = SparkContext(conf=conf)
spark = SparkSession(sc)
df_dict = {
'a': {
"1": "stuff", "2": "stuff2"
},
"d": {
"1": [(1, 2), (3, 4)], "2": [(1, 2), (3, 4)]
}
}
df = pd.DataFrame(df_dict)
ddf = spark.createDataFrame(df)
row_breakdown = ddf.set_index(["a"])["d"].apply(pd.Series).stack()
AttributeError: 'DataFrame' object has no attribute 'set_index'
Apparently, Spark doesn't support indexing. Any pointers appreciated.
ahere? All the information you need to construct the output is ind, unless I'm missing something.row_breakdown = spark.createDataFrame(chain.from_iterable(df_dict["d"].values()), ["value1", "value2"])(wherechainisfrom itertools import chain)