В DF есть несколько ячеек, которые содержат список
['AsianBeauty', 'AsianBeautyAdvice','SkincareAddiction', 'abdiscussion']
, и это отдельная ячейка, которую необходимо разбить на отдельные строки в одном и том же столбце (Product Name
).Однако это должно быть сделано при сохранении ассоциации между столбцом Product Name
и каждым из двух других столбцов (которые содержат строки, которые должны быть разбиты).Я использовал этот пост , чтобы сделать именно это, сохраняя при этом связь нетронутой.Вот подход, который я использовал, с комментариями в коде и объяснением верхнего уровня, показанными отдельно
Raw DF от OP
import pandas as pd
df_final = pd.DataFrame()
df_final['Product Name'] = ('dr. jart+ mask heroes face savers',
'moon juice beauty shroom exfoliating acid potion',
'laneige kiss and make up set')
df_final['Subreddit'] = (None, ['scacjdiscussion'], ['AsianBeauty',
'AsianBeautyAdvice','SkincareAddiction',
'abdiscussion'])
df_final['Times Mentioned'] = (None, [1], [4,1,1,1])
print(df_final)
Необработанные данные (df_final
)
Product Name Subreddit Times Mentioned
0 dr. jart+ mask heroes face savers None None
1 moon juice beauty shroom exfoliating acid potion [scacjdiscussion] [1]
2 laneige kiss and make up set [AsianBeauty, AsianBeautyAdvice, SkincareAddiction, abdiscussion] [4, 1, 1, 1]
Столбец необработанных данных dtypes
print(df_final.dtypes)
Product Name object
Subreddit object
Times Mentioned object
dtype: object
Код для разнесения строк и создания окончательного DF
exploded_dfs = []
for _, row in df_final.iterrows():
if all(row): # if a row does contain all non-None values
# Put 1st pair of columns into single DF, exploding single
# cell into multiple rows as needed
df1 = pd.concat([pd.Series(row['Product Name'], row['Subreddit'][:])])\
.reset_index()
# Assign column names
df1.columns = ['Subreddit', 'Product Name']
# Put 2nd pair of columns into single DF, exploding single
# cell into multiple rows as needed
df2 = pd.concat([pd.Series(row['Product Name'], row['Times Mentioned'][:])])\
.reset_index()
# Assign column names
df2.columns = ['Times Mentioned', 'Product Name']
# Perform INNER JOIN on DFs with exploded row contents
# & drop duplicated column
merged = pd.concat([df1, df2], axis=1)
merged = merged.loc[:,~merged.columns.duplicated()]
# Swap 1st and 2nd columns
cols = list(merged)
cols.insert(0, cols.pop(cols.index('Product Name')))
merged = merged.loc[:, cols]
else: # if a row does not contain all non-None values
# Create single row DF with no changes
merged = pd.DataFrame(columns=['Product Name', 'Subreddit',
'Times Mentioned'])
# Append row to DF
merged.loc[0] = row
exploded_dfs.append(merged)
# Vertically concatenate DFs in list
print(pd.concat(exploded_dfs, axis=0).reset_index(drop=True))
Вот вывод
Product Name Subreddit Times Mentioned
0 dr. jart+ mask heroes face savers None None
1 moon juice beauty shroom exfoliating acid potion scacjdiscussion 1
2 laneige kiss and make up set AsianBeauty 4
3 laneige kiss and make up set AsianBeautyAdvice 1
4 laneige kiss and make up set SkincareAddiction 1
5 laneige kiss and make up set abdiscussion 1
Краткое объяснение шагов
- итерации по всем строкам
- обратите внимание, что если строка содержит какие-либо значения
None
, она будет принята как есть, поэтомупредполагается, что эта строка не нуждается в очистке: эта строка будет просто добавлена к одной строке DF
- для первой строки в необработанном DF, который не содержит все
None
- разнесите ячейку из первого столбца со списком (
Subreddit
) в столбец, если необходимо (объяснено в этот вопрос ) - горизонтально сцепленная взорванная ячейка (теперьв виде нескольких строк) со строкой из столбца без списка (
Product Name
);это дает очищенному DF df1
- повторение последних 2 шагов выше, используя второй столбец со списком (
Times Mentioned
);это дает очищенному DF df1
- по горизонтали объединить 2 очищенных DF в новый DF с именем
merged
- , повторите описанную выше процедуру для всех строк в необработанном DF и добавьте очищенный DF в пустой список
- собрать окончательный DF с вертикальной конкатенацией всех DF в списке
Информация о пакете
pandas==0.23.4
Версия Python
Python 2.7.15rc1