我想比较一列的数据帧与多列的另一数据帧,并返回具有最大匹配百分比的列的标题。
我在熊猫中找不到任何匹配功能。第一数据帧第一列:
cars
----
swift
maruti
wagonor
hyundai
jeep
第一数据帧第二列:
bikes
-----
RE
Ninja
Bajaj
pulsar
一列数据框:
words
---------
swift
RE
maruti
waganor
hyundai
jeep
bajaj
所需的输出:
100% match header - cars
答案 0 :(得分:3)
尝试使用pandas DataFrame的isin功能。假设df是您的第一个数据帧,而word是一个列表:
In[1]: (df.isin(words).sum()/df.shape[0])*100
Out[1]:
cars 100.0
bikes 20.0
dtype: float64
您可能需要在df和单词列表中小写字符串,以避免出现大小写问题。
答案 1 :(得分:1)
您可以先将这些列放入列表中:
dfCarsList = df['cars'].tolist()
dfWordsList = df['words'].tolist()
dfBikesList = df['Bikes'].tolist()
然后迭代列表以进行比较:
numberCars = sum(any(m in L for m in dfCarsList) for L in dfWordsList)
numberBikes = sum(any(m in L for m in dfBikesList) for L in dfWordsList)
您可以使用的数字大于输出的数字。
答案 2 :(得分:1)
使用numpy.in1d
和ndarray.mean
构造Series
,然后调用Series.idxmax
和max
方法:
# Setup
df1 = pd.DataFrame({'cars': {0: 'swift', 1: 'maruti', 2: 'waganor', 3: 'hyundai', 4: 'jeep'}, 'bikes': {0: 'RE', 1: 'Ninja', 2: 'Bajaj', 3: 'pulsar', 4: np.nan}})
df2 = pd.DataFrame({'words': {0: 'swift', 1: 'RE', 2: 'maruti', 3: 'waganor', 4: 'hyundai', 5: 'jeep', 6: 'bajaj'}})
match_rates = pd.Series({col: np.in1d(df1[col], df2['words']).mean() for col in df1})
print('{:.0%} match header - {}'.format(match_rates.max(), match_rates.idxmax()))
[出]
100% match header - cars
答案 3 :(得分:0)
这是一个带有函数的解决方案,该函数返回具有最大匹配百分比的列的元组(column_name, match_percentage)
。它接受熊猫数据框(在您的示例中为自行车和汽车)和一系列(单词)作为参数。
def match(df, se):
max_matches = 0
max_col = None
for col in df.columns:
# Get the number of matches in a column
n_matches = sum([1 for row in df[col] if row in se.unique()])
if n_matches > max_matches:
max_col = col
max_matches = n_matches
return max_col, max_matches/df.shape[0]
以您的示例为例,您应该获得以下输出。
df = pd.DataFrame()
df['Cars'] = ['swift', 'maruti', 'wagonor', 'hyundai', 'jeep']
df['Bikes'] = ['RE', 'Ninja', 'Bajaj', 'pulsar', '']
se = pd.Series(['swift', 'RE', 'maruti', 'wagonor', 'hyundai', 'jeep', 'bajaj'])
In [1]: match(df, se)
Out[1]: ('Cars', 1.0)