我有一個資料集如下:
| 姓名 | 元素 |
|---|---|
| 貓 | 朋友,朋友,朋友 |
| 狗 | 朋友,朋友 |
| 烏鴉 | 朋友 |
| 牛 | 朋友,國內 |
| 鸚鵡 | 朋友, 朋友, 國內的, 國內的 |
| 兔子 | 國內的 |
我必須洗掉元素列中僅包含出現朋友的所有行。那是我的最終輸出應該如下所示:
| 姓名 | 元素 |
|---|---|
| 牛 | 朋友,國內 |
| 鸚鵡 | 朋友, 朋友, 國內的, 國內的 |
| 兔子 | 國內的 |
我嘗試通過創建一個串列然后使用以下方法將其洗掉,代碼如下:
list = list(data["Elements"])
list[:] = [x for x in list if x != 'friend']
但是使用上面的代碼只有一個實體,包含一次朋友,即與 crow 對應的元素被洗掉,并且無法將剩余資料映射到相應的“名稱”列。
如何移除friend的所有實體,即Cat、Dog和Crow對應的元素。另外,我如何能夠將資料映射到相應的“名稱”列?
還有其他方法嗎?
請指導。
uj5u.com熱心網友回復:
我將假設可能會有更多型別的元素和可能沒有元素的行。
我假設 df['elements'] 是一個字串(因為您沒有給出代碼示例來查看格式)。該串列將是 [item.strip() for item in df['elements'].split(',')]。
然后我會將串列轉換為一個集合,看看是否是 {'friend'}
def make_set(s):
return set([item.strip() for item in s.split(',')])
cond = df['elements'].apply(lambda s: make_set(s) != {'friend'})
df[cond]
uj5u.com熱心網友回復:
您可以將元素串列轉換為集合,這是一個類似于串列但不能重復的物件(以及其他功能)。將其替換為
list[:] = [x for x in list if set(x) != set('friend')]
為了洗掉相應的名稱,最好不要使用串列推導,而是使用 for 回圈,就像這樣(以兩個串列的形式輸出)
for name, element in zip(data["Name"], data["Elements"]):
if set(element.split(", ")) != set(["friend"]) and element != "friend":
cleanList.append((name,element))
cleanList = list(zip(*cleanList))
print(cleanList)
uj5u.com熱心網友回復:
試試這個:
ix = df['Elements'].str.split(r',\s*', regex=True).apply(set) != {'friend'}
newdf = df.loc[ix].reset_index(drop=True).copy()
>>> newdf
Name Elements
0 Cow friend, domestic
1 Parrot friend, friend, domestic, domestic
2 Rabbit domestic
注意:如果你正在使用pandas < 1.4(你不應該),那么洗掉regex=True引數:
ix = df['Elements'].str.split(r',\s*').apply(set) != {'friend'}
解釋
第一部分str.split(...)將文本值拆分Elements為串列。我們應用set這些串列來獲取集合。然后我們制作一個掩碼ix,這些集合與單例不同{'friend'}。
第二部分根據該掩碼進行選擇,重置RangeIndex以便您獲得 rows 0, 1, 2...。最后一點.copy()是確保它newdf有自己的資料,而不僅僅是原始資料中的一個切片。如果您要進一步修改它,這會有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/478272.html
上一篇:給定串列中數字的平均值
下一篇:將串列的元組轉換為串列
