這是一個關于 從基礎到進階的練習題系列多行多列表單元素是,來源于 上的 / 。這個項目從基礎到進階,可以檢驗你有多么了解 。
我會挑選一些題目,并且提供比原題庫更多的解決方法以及更詳盡的解析。
計劃每天更新一期,希望各位小伙伴先自行思考,再查看答案。如果對你有幫助,記得轉發推薦給你的好友!
上期文章:每天一題-題目18:分組填充缺失值
數據處理,從入門到高級應用,核心知識點圖解教學,歡迎關注我的專欄:
后臺回復"數據",可以下載本題數據集
如下數據:
import pandas as pd
import numpy as np
df = pd.read_csv('chipotle.tsv',
sep='\t',
converters={'item_price': lambda x: float(x[1:-1])})
數據描述:
前面章節講解過的知識點,本文不再講解!
這次只需要4個訂單的數據即可:
orders = [311, 1828, 328, 1355]

df.query('order_id in @orders')
然后把同一個訂單的 串起來:
orders = [311, 1828, 328, 1355]
df = (
df.query('order_id in @orders')
.groupby('order_id').agg({'item_name':','.join})
.reset_index()
)
需求:
把 拆開,變回每個 一行數據
下面是答案了
橫向 + 豎向的拆分
第一步是把"串起來"的 拆分:
df.assign(item_name = df.item_name.str.split(','))
現在的 里面全是 列表對象(list):
(

df.assign(item_name = df.item_name.str.split(','))
['item_name'].apply(type)
)
此時,如果你在使用 0.25或以上版本,那么可以:
(
df.assign(item_name = df.item_name.str.split(','))
.explode('item_name')
)
點評:
記住次序,先讓單元格里面的內容變成列表,然后對列做
注意返回結果的行索引,這能給出另一種解法的提示
重排索引
很不幸,如果你使用比較舊版本的多行多列表單元素是,怎么辦?
我們使用倒推法找解決思路。
只看 列,怎么從左邊得到右邊的結果?
實際就是有一個 列表,里面的元素都是列表,怎么展平成一個列表:
from itertools import chain
list(chain.from_iterable([[1,2,3],[4,5]]))
輸出:
[1, 2, 3, 4, 5]
關于 可以關注我的相關系列教程
也就是:
from itertools import chain
dfx = df.assign(item_name = df.item_name.str.split(','))
names = list(chain.from_iterable(dfx['item_name']))
names
輸出:
['Steak Salad',
'Steak Bowl',
'Chips and Guacamole',
'Carnitas Soft Tacos',
'Chicken Bowl',

'Chips and Guacamole',
'Chicken Burrito',
'Chicken Bowl',
'Chips and Guacamole',
'Canned Soft Drink']
接下來,怎么可以從4行,按每一行的 里面的列表元素數量,拆分成多行?
可以重復多行數據:
df.reindex([0,0,1,1,2,2,3,3])
怎么知道每個訂單需要拆分的行數:
dfx = df.assign(item_name = df.item_name.str.split(','))
dfx['item_name'].str.len()
怎么按這個數量,生成對應的行索引值:
dfx = df.assign(item_name = df.item_name.str.split(','))
lens = dfx['item_name'].str.len()
np.repeat(lens.index,lens)
輸出:
Int64Index([0, 0, 0, 0, 1, 1, 2, 3, 3, 3], dtype='int64')
行2也可以使用:
lens = dfx['item_name'].apply(len)
至此,把所有技巧連起來即可:
from itertools import chain
dfx = df.assign(item_name = df.item_name.str.split(','))
# 展開 list 中 list
names = list(chain.from_iterable(dfx['item_name']))
# 展開行
lens = dfx['item_name'].str.len()
idx = np.repeat(lens.index,lens)
dfx = dfx.reindex(idx)
dfx['item_name'] = names
dfx
這就能得到與直接使用 一樣的結果
總結:
.chain 展開 list 中 . 重復生成指定次數的數據. 按指定行索引值,生成重復數據