根据索引和列将函数应用于数据框中的每个单元格
Applying function to every cell in a Dataframe based on index and col
我有一个 pandas 数据框,其格式与 and I'm trying to achieve the same result. In my case, I am calculating the fuzz-ratio 中行索引和对应列之间的格式完全相同。
如果我尝试此代码(基于对链接问题的回答)
def get_similarities(x):
return x.index + x.name
test_df = test_df.apply(get_similarities)
行索引和列名称的连接按单元格方式发生,正如预期的那样。 运行 type(test_df)
returns pandas.core.frame.DataFrame
,符合预期。
但是,如果我像这样调整代码以适应我的场景
def get_similarities(x):
return fuzz.partial_ratio(x.index, x.name)
test_df = test_df.apply(get_similarities)
没用。我取回了一个系列,而不是数据框(该函数的 return 类型是 int
)
我不明白为什么这两个样本的行为不一样,也不明白如何修复我的代码,所以它 return 是一个数据框,行索引之间的每个单元格 fuzzy.ratio
该单元格的名称和该单元格的列名称。
下面的方法呢?
假设我们有两组字符串:
In [245]: set1
Out[245]: ['car', 'bike', 'sidewalk', 'eatery']
In [246]: set2
Out[246]: ['walking', 'caring', 'biking', 'eating']
解决方案:
In [247]: from itertools import product
In [248]: res = np.array([fuzz.partial_ratio(*tup) for tup in product(set1, set2)])
In [249]: res = pd.DataFrame(res.reshape(len(set1), -1), index=set1, columns=set2)
In [250]: res
Out[250]:
walking caring biking eating
car 33 100 0 33
bike 25 25 75 25
sidewalk 73 20 22 36
eatery 17 33 0 50
花了一些时间,但我想通了。问题来自这样一个事实,即 DataFrame.apply
要么按列应用,要么按行应用,而不是逐个单元格应用。因此,您的 get_similarities
函数实际上是一次访问整行或整列数据!默认情况下,它会获取整个列 - 因此要解决您的问题,您只需创建一个 returns 列表的 get_similarities
函数,您可以在其中手动调用每个元素的 fuzz.partial_ratio
,就像这样:
import pandas as pd
from fuzzywuzzy import fuzz
def get_similarities(x):
l = []
for rname in x.index:
print "Getting ratio for %s and %s" % (rname, x.name)
score = fuzz.partial_ratio(rname,x.name)
print "Score %s" % score
l.append(score)
print len(l)
print
return l
a = pd.DataFrame([[1,2],[3,4]],index=['apple','banana'], columns=['aple','banada'])
c = a.apply(get_similarities,axis=0)
print c
print type(c)
我将我的打印语句留在了它们中,这样您就可以看到 DataFrame.apply
调用为您自己做了什么 -- 那就是它为我点击的时候。
有一种方法可以通过 DataFrame.apply
和一些行操作来完成此操作。
假设'test_df`如下:
In [73]: test_df
Out[73]:
walking caring biking eating
car carwalking carcaring carbiking careating
bike bikewalking bikecaring bikebiking bikeeating
sidewalk sidewalkwalking sidewalkcaring sidewalkbiking sidewalkeating
eatery eaterywalking eaterycaring eaterybiking eateryeating
In [74]: def get_ratio(row):
...: return row.index.to_series().apply(lambda x: fuzz.partial_ratio(x,
...: row.name))
...:
In [75]: test_df.apply(get_ratio)
Out[75]:
walking caring biking eating
car 33 100 0 33
bike 25 25 75 25
sidewalk 73 20 22 36
eatery 17 33 0 50
我有一个 pandas 数据框,其格式与
如果我尝试此代码(基于对链接问题的回答)
def get_similarities(x):
return x.index + x.name
test_df = test_df.apply(get_similarities)
行索引和列名称的连接按单元格方式发生,正如预期的那样。 运行 type(test_df)
returns pandas.core.frame.DataFrame
,符合预期。
但是,如果我像这样调整代码以适应我的场景
def get_similarities(x):
return fuzz.partial_ratio(x.index, x.name)
test_df = test_df.apply(get_similarities)
没用。我取回了一个系列,而不是数据框(该函数的 return 类型是 int
)
我不明白为什么这两个样本的行为不一样,也不明白如何修复我的代码,所以它 return 是一个数据框,行索引之间的每个单元格 fuzzy.ratio
该单元格的名称和该单元格的列名称。
下面的方法呢?
假设我们有两组字符串:
In [245]: set1
Out[245]: ['car', 'bike', 'sidewalk', 'eatery']
In [246]: set2
Out[246]: ['walking', 'caring', 'biking', 'eating']
解决方案:
In [247]: from itertools import product
In [248]: res = np.array([fuzz.partial_ratio(*tup) for tup in product(set1, set2)])
In [249]: res = pd.DataFrame(res.reshape(len(set1), -1), index=set1, columns=set2)
In [250]: res
Out[250]:
walking caring biking eating
car 33 100 0 33
bike 25 25 75 25
sidewalk 73 20 22 36
eatery 17 33 0 50
花了一些时间,但我想通了。问题来自这样一个事实,即 DataFrame.apply
要么按列应用,要么按行应用,而不是逐个单元格应用。因此,您的 get_similarities
函数实际上是一次访问整行或整列数据!默认情况下,它会获取整个列 - 因此要解决您的问题,您只需创建一个 returns 列表的 get_similarities
函数,您可以在其中手动调用每个元素的 fuzz.partial_ratio
,就像这样:
import pandas as pd
from fuzzywuzzy import fuzz
def get_similarities(x):
l = []
for rname in x.index:
print "Getting ratio for %s and %s" % (rname, x.name)
score = fuzz.partial_ratio(rname,x.name)
print "Score %s" % score
l.append(score)
print len(l)
print
return l
a = pd.DataFrame([[1,2],[3,4]],index=['apple','banana'], columns=['aple','banada'])
c = a.apply(get_similarities,axis=0)
print c
print type(c)
我将我的打印语句留在了它们中,这样您就可以看到 DataFrame.apply
调用为您自己做了什么 -- 那就是它为我点击的时候。
有一种方法可以通过 DataFrame.apply
和一些行操作来完成此操作。
假设'test_df`如下:
In [73]: test_df
Out[73]:
walking caring biking eating
car carwalking carcaring carbiking careating
bike bikewalking bikecaring bikebiking bikeeating
sidewalk sidewalkwalking sidewalkcaring sidewalkbiking sidewalkeating
eatery eaterywalking eaterycaring eaterybiking eateryeating
In [74]: def get_ratio(row):
...: return row.index.to_series().apply(lambda x: fuzz.partial_ratio(x,
...: row.name))
...:
In [75]: test_df.apply(get_ratio)
Out[75]:
walking caring biking eating
car 33 100 0 33
bike 25 25 75 25
sidewalk 73 20 22 36
eatery 17 33 0 50