簡體   English   中英

根據索引AND列名稱逐個單元格填充整個數據幀?

[英]fill in entire dataframe cell by cell based on index AND column names?

我有一個數據框,其中行索引和列標題應確定每個單元格的內容。 我正在使用以下df的更大版本:

df = pd.DataFrame(index = ['afghijklde', 'afghijklmde', 'ade', 'afghilmde', 'amde'], 
                  columns = ['ae', 'azde', 'afgle', 'arlde', 'afghijklbcmde'])

具體來說,我想應用自定義函數edit_distance()或等效函數edit_distance()有關函數代碼,請參見此處 ),該函數計算兩個字符串之間的差異得分。 兩個輸入是行名和列名。 以下工作正常,但速度非常慢:

for seq in df.index:
    for seq2 in df.columns:
        df.loc[seq, seq2] = edit_distance(seq, seq2) 

這產生了我想要的結果:

            ae  azde    afgle   arlde   afghijklbcmde
afghijklde  8    7        5       6          3
afghijklmde 9    8        6       7          2
ade         1    1        3       2          10
afghilmde   7    6        4       5          4
amde        2    1        3       2          9

有什么更好的方法,也許使用applymap() 我使用applymap()applydf.iterrows()嘗試過的所有方法均返回了AttributeError: "'float' object has no attribute 'index'"類型的錯誤AttributeError: "'float' object has no attribute 'index'" 謝謝。

事實證明,還有一種更好的方法可以做到這一點。 上面的onepan字典理解答案很好,但是以隨機順序返回df索引和列。 使用嵌套的.apply()可以以大約相同的速度完成相同的操作,並且不會更改行/列的順序。 關鍵是不要掛斷先命名df的行和列,然后再填充值。 取而代之的是,將未來的索引和列視為獨立的熊貓系列。

series_rows = pd.Series(['afghijklde', 'afghijklmde', 'ade', 'afghilmde', 'amde'])
series_cols = pd.Series(['ae', 'azde', 'afgle', 'arlde', 'afghijklbcmde'])

df = pd.DataFrame(series_rows.apply(lambda x: series_cols.apply(lambda y: edit_distance(x, y))))
df.index = series_rows
df.columns = series_cols

您可以使用理解功能,在我的電腦上將其提高〜4.5倍

first = ['afghijklde', 'afghijklmde', 'ade', 'afghilmde', 'amde']
second = ['ae', 'azde', 'afgle', 'arlde', 'afghijklbcmde']
pd.DataFrame.from_dict({f:{s:edit_distance(f, s) for s in second} for f in first}, orient='index')

# output
#              ae  azde  afgle arlde  afghijklbcmde
# ade          1   2     2     2      2
# afghijklde   1   3     4     4      9
# afghijklmde  1   3     4     4      10
# afghilmde    1   3     4     4      8
# amde         1   3     3     3      3

# this matches to edit_distance('ae', 'afghijklde') == 8, e.g.

注意,我將此代碼用於edit_distance(您的鏈接中的第一個響應):

def edit_distance(s1, s2):
    if len(s1) > len(s2):
        s1, s2 = s2, s1

    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2+1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
        distances = distances_
    return distances[-1]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM