Saya menggunakan data massal (Daftar simbol Valid BPK) dari situs web BPK. Saya telah membaca csv menjadi pandas df, dan 30 baris pertama (lebih dari 260K) adalah:

    SYMBOL  level   not-allocatable additional-only
1   A   2   True    False
2   A01 4   True    False
3   A01B    5   True    False
4   A01B 1/00   7   False   False
5   A01B 1/02   8   False   False
6   A01B 1/022  9   False   False
7   A01B 1/024  9   False   False
8   A01B 1/026  9   False   False
9   A01B 1/028  9   False   False
10  A01B 1/04   9   False   False
11  A01B 1/06   8   False   False
12  A01B 1/065  9   False   False
13  A01B 1/08   9   False   False
14  A01B 1/10   9   False   False
15  A01B 1/12   9   False   False
16  A01B 1/14   9   False   False
17  A01B 1/16   8   False   False
18  A01B 1/165  9   False   False
19  A01B 1/18   9   False   False
20  A01B 1/20   8   False   False
21  A01B 1/22   8   False   False
22  A01B 1/222  9   False   False
23  A01B 1/225  10  False   False
24  A01B 1/227  9   False   False
25  A01B 1/24   8   False   False
26  A01B 1/243  9   False   False
27  A01B 1/246  9   False   False
28  A01B 3/00   7   False   False
29  A01B 3/02   8   False   False

Nilai level membuat hierarki. Jadi node A01B 1/00 ​​adalah level 7 dan anak dari A01B. A01B 1/02 adalah level 8 dan anak dari A01B 1/00 ​​& A01b 3/00 adalah anak dari A01B.

Yang saya inginkan adalah cara membuat kolom baru bernama PARENT yang berisi SYMBOL dari induk langsung node. Misalnya, saya mengedit csv di Excel untuk menampilkan hasil yang diinginkan dari beberapa baris pertama:

The dataframe after adding the parent column

Catatan: tidak ada simbol level 1, 3, atau 6. Ada beberapa simbol level 2. Tidak ada induk untuk simbol level 2, induk dari simbol level 4 dapat diberikan simbol level 2 pertama di atasnya, dan induk dari simbol level 7 juga dapat diberikan simbol level 5 pertama di atasnya.

EDIT: Saya perlu menjelaskan dengan lebih baik cara menentukan induk simpul. Nilai level dan posisi baris adalah semua yang diperlukan untuk menentukan induk.  Pohon yang menunjukkan orang tua dan anak python pandas tree

0
Britt 29 Mei 2019, 23:34

2 jawaban

Jawaban Terbaik

Berikut metode lain. GetParent() mengembalikan fungsi yang melacak simbol terbaru untuk setiap level dan mengembalikan induk dari level saat ini. Menggunakannya di pandas.apply() membuat kolom dengan simbol induk.

def GetParent():
    #            0  1  2  3  4  5  6  7  8  9  10
    hierarchy = [0, 0, 0, 0, 2, 4, 0, 5, 7, 8, 9]
    parent = [' ']*11

    def func(row):
        #print(row)
        symbol,level = row[['SYMBOL', 'level']]

        parent_level = hierarchy[level]
        parent_symbol = parent[parent_level]

        parent[level] = symbol

        return pd.Series([parent_symbol], index=['parent'])

    return func

# create a column with the parents
parents = df.apply(GetParent(), axis=1)
df = pd.concat([df, parents], axis=1)

df

Keluaran:

    SYMBOL  level   na      ao      parent
0   A           2   True    False   
1   A01         4   True    False   A
2   A01B        5   True    False   A01
3   A01B 1/00   7   False   False   A01B
4   A01B 1/02   8   False   False   A01B 1/00
5   A01B 1/022  9   False   False   A01B 1/02
6   A01B 1/024  9   False   False   A01B 1/02
7   A01B 1/026  9   False   False   A01B 1/02
8   A01B 1/028  9   False   False   A01B 1/02
9   A01B 1/04   9   False   False   A01B 1/02
10  A01B 1/06   8   False   False   A01B 1/00
11  A01B 1/065  9   False   False   A01B 1/06
12  A01B 1/08   9   False   False   A01B 1/06
...
1
RootTwo 14 Juni 2019, 05:37

Dalam jawaban ini saya berasumsi bahwa orang tua langsung Anda selalu berada dalam satu baris di atas milik Anda karena itulah yang diharapkan oleh output dan diagram Anda.

Dengan hipotesis ini, kita dapat, untuk setiap baris, mengambil baris terdekat dengan tingkat di bawah baris:

import pandas as pd

data={"Symbol":["A", "A01", "A01B", "A01B 1/00", "A01B 1/02", "A01B 1/022", "B"], "level":[2,4,5,7,8,9,2]}

df=pd.DataFrame(data=data)
df['Parent'] = ''

for index, row in df.iterrows():
    # We look at the potential parents
    potential_parents = df.loc[df.index.isin([x for x in range(index)]) & (df['level'] < row['level']), 'Symbol']
    # And we take the last one as our parent
    if len(potential_parents) == 0: 
        df.loc[index, 'Parent'] = ''
    else:
        df.loc[index, 'Parent'] = potential_parents.iloc[-1]

Keluaran:

       Symbol  level     Parent
0           A      2           
1         A01      4          A
2        A01B      5        A01
3   A01B 1/00      7       A01B
4   A01B 1/02      8  A01B 1/00
5  A01B 1/022      9  A01B 1/02
6           B      2           
1
vlemaistre 13 Juni 2019, 14:35