![](/img/trans.png)
[英]How to add values from a Pandas Series to a Dataframe column without duplicates
[英]How to create a pandas dataframe of unique values fetched from column with no duplicates
我有一個熊貓數據框df
:
import pandas as pd
df = pd.DataFrame({"ID": [2,3,4,5,6,7,8,9,10],
"type" :["A", "B", "B", "A", "A", "B", "A", "A", "A"],
"F_ID" :["0", "[7 8 9]", "[10]", "0", "[2]", "0", "0", "0", "0"]})
看起來像:
F_ID ID type
0 0 2 A
1 [7 8 9] 3 B
2 [10] 4 B
3 0 5 A
4 [2] 6 A
5 0 7 B
6 0 8 A
7 0 9 A
8 0 10 A
在此,F_ID是一列,它基於某些計算來告訴哪些記錄與該關節記錄匹配。 它給出了匹配的ID值。 因此,ID 3與ID 7和8匹配。
我想要所有B
類型ID及其相關記錄的列表。 如果在單獨的列的F_ID列中提到匹配ID,則該列的編號可能會根據值而有所不同,如下所示:
ID type F_ID_1 F_ID_2
3 B 8 9
4 B 10
7 B
我不需要提到的那些B類型的F_ID的值。例如,ID 3具有7、8、9作為匹配ID,但是由於第7個ID是B類型,因此不應將其稱為F_ID,並且僅必須列出8和9。
如何使用python中的pandas做到這一點?
如果我了解您的意圖,那么F_ID是列表的字符串表示形式?
如果是這樣,請將其轉換為實際列表:
import numpy as np
import pandas as pd
df = pd.DataFrame({"ID": [2,3,4,5,6,7,8,9,10],
"type" :["A", "B", "B", "A", "A", "B", "A", "A", "A"],
"F_ID" :["0", "[7 8 9]", "[10]", "0", "[2]", "0", "0", "0", "0"]})
# convert the string representations of list structures to actual lists
F_ID_as_series_of_lists = df["F_ID"].str.replace("[","").str.replace("]","").str.split(" ")
#type(F_ID_as_series_of_lists) is pd.Series, make it a list for pd.DataFrame.from_records
F_ID_as_records = list(F_ID_as_series_of_lists)
f_id_df = pd.DataFrame.from_records(list(F_ID_as_records)).fillna(np.nan)
f_id_df
現在,讓我們將拆分后的F_ID
加入到原始DataFrame中
combined_df = df.merge(f_id_df, left_index = True, right_index = True, how = "inner")
combined_df = combined_df.drop("F_ID", axis = 1).sort_values(["type", "ID"])
combined_df
但是,我們需要省略在同一type
以ID
出現的F_ID
,即由於7
是type == "B"
的ID
,因此我們想在ID == 3
和type == "B"
將其排除,即使盡管它在F_ID
的列表中。
為此,我們創建ID
/ type
到F_ID
映射。
mapping_df = pd.DataFrame(combined_df.set_index(["ID", "type"]).stack()).reset_index().drop("level_2", axis = 1)
mapping_df.columns = ["ID", "type", "F_ID"]
mapping_df
現在進行過濾,我們可能可以做一些令人印象深刻的聯接,但是如果我們不得不回到這個例子,則更容易閱讀該示例的查詢:
def is_fid_of_same_type(row, df):
query = "ID == {row_fid} & type == '{row_type}'".format(
row_fid = row["F_ID"],
row_type = row["type"]
)
matches_df = df.query(query)
row["fid_in_type_id"] = len(matches_df) > 0
return row
現在,將此功能應用於每一行,並將確實顯示為F_ID
的行作為同一type
的ID
F_ID
。
df = mapping_df.apply(lambda row: is_fid_of_same_type(row, mapping_df), axis = 1)
df = df[df["fid_in_type_id"] == False].drop("fid_in_type_id", axis = 1)
df
然后, F_ID
作為列表而不是單獨的行,請使用DataFrame.groupby()
然后apply(list)
。
group_columns = ['type', 'ID']
df = df.groupby(group_columns)['F_ID'].apply(list).reset_index()
df = df.sort_values(group_columns).set_index(group_columns)
df
結果是:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.