Python 根据索引和列名逐个单元格填写整个数据帧?

Python 根据索引和列名逐个单元格填写整个数据帧?,python,pandas,Python,Pandas,我有一个数据框架,其中行索引和列标题应该决定每个单元格的内容。我正在使用以下df的更大版本: df = pd.DataFrame(index = ['afghijklde', 'afghijklmde', 'ade', 'afghilmde', 'amde'], columns = ['ae', 'azde', 'afgle', 'arlde', 'afghijklbcmde']) 具体来说,我想应用自定义函数edit_distance()或等效函数(请参

我有一个数据框架,其中行索引和列标题应该决定每个单元格的内容。我正在使用以下df的更大版本:

df = pd.DataFrame(index = ['afghijklde', 'afghijklmde', 'ade', 'afghilmde', 'amde'], 
                  columns = ['ae', 'azde', 'afgle', 'arlde', 'afghijklbcmde'])
具体来说,我想应用自定义函数
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()
apply
df.iterrows()
尝试的所有操作都返回了类似于
AttributeError的错误:“'float'对象没有属性'index'”
。谢谢。

您可以使用理解功能,在我的电脑上可以将速度提高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.
注:我使用此代码编辑距离(链接中的第一个响应):


事实证明有更好的方法来做到这一点。上面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

这样做很慢的原因是因为有许多python嵌套for循环,不仅在数据帧控制流中,而且在距离函数本身中。要加快速度,您需要尝试将所有这些都矢量化。Applymap并没有做到这一点,它只是在元素方面进行应用。就个人而言,为了真正优化它,我会考虑利用单词的一些固有结构,如果它们以一种巧妙的方式在索引中排序的话。您甚至可以使用估计值,并大大减少您试图检测的范围。谢谢,但这似乎为每个单元格生成了错误的值,其中三个单元格为NaN,尽管它们之间的成对距离是整数。我得到了添加的输出。当我测试它时,它匹配-你有一个失败的具体例子吗?注意,我刚才输入了一个错误并更正了听写理解。实际上,我误读了你的示例输出。您是否试图在
(索引,索引)
(索引,列)
上运行
编辑距离
?谢谢,您的代码现在工作正常。我还更新了我的OQ,修正了df中的一个打字错误。你介意我问一下,为什么用字典理解而不是列表理解?解析您的代码花了我一段时间,我不确定下次是否可以在概念上复制它。您也可以使用列表comps来完成,但使用dict可以省去命名索引和列的步骤。我的代码中的dict是与edit_distance的标签输出相关联的索引(例如
{'ade':{'azde':2}
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