[英]Pandas DataFrames: How to locate rows using index values in existing dataframe based on values from another dataframe column?
[英]How to fill the Pandas Dataframe based on values from another two dataframes
我有 4 个熊猫数据框,前两个是分类值和数值 df,
Cat_data = [
['Color', 'red', 0.2543],
['Color', 'orange',0.1894],
['Color', 'yellow',-0.2836],
['Fruit', 'orange', -1.3647],
['Fruit','banana',0.3648]
]
Cat_df = pd.DataFrame(Cat_data, columns = ['Variable', 'Cats', 'Value'])
Num_data = [
['Quantity', '-inf', '5', 0.2145],
['Quantity', '5', '10', 0.0268],
['Quantity', '10', 'inf', -0.5421],
['Rating', '-inf', '0.5', 0.6521],
['Rating','0.5', 'inf', -0.4378],
]
Num_df = pd.DataFrame(Num_data, columns = ['Variable', 'Inclusive', 'Exclusive', 'Value'])
在 Num_data 'Inclusive' 和 'Exclusive' 是检查值,
在第一条记录上说 >= -inf 和 < 5 ,
第二个记录值 >=5 和 < 10 相同,值来自 Actual_df
第三个数据框是实际值
Actual_data = [
['yellow', 'banana', '4', '0.5']
]
Actual_df = pd.DataFrame(Actual_data, columns = ['Color', 'Fruit', 'Quantity', 'Rating'])
第四个是列名与 Actual_df 相同的 Value DataFrame
Value_df = pandas.DataFrame(numpy.zeros((1, 4)),
columns = ['Color', 'Fruit', 'Quantity', 'Rating'])
我需要用对应于 Actual_data 中数据的 Cat_data 和 Num_data 'Value' 列中的 'Value' 填充 Value_df,我不确定如何合并四个 df 并取值来检查 Inclusive 和 Exclusive 列。
在实际数据中,我们有 'yellow', 'banana', '4', '0.5' 对应的值
黄色在 Cat_df 中为 -0.2836
香蕉在 Cat_df 中为 0.3648
数量在 Num_df 中为 0.2145
评分在 Num_df 中为 -0.4378
我的 Value_df 结果数据帧将是
Color Fruit Quantity Rating
-0.2836 0.3648 0.2145 -0.4378
对于 Cat_data,我确实喜欢
Value_df['Color'] = Actual_df['Color'].map(Cat_df.set_index('Cats')['Value'])
颜色和水果都是橙色的问题,取哪个值是问题,所以我也必须匹配变量,我得到错误
InvalidIndexError: Reindexing only valid with uniquely valued Index objects
如果您可以依赖Num_df
中的范围不重叠的事实,您可以按如下方式执行此操作。 注意我定义了一些辅助函数,你也可以不用,但我认为它更容易阅读。
# convert the datatypes (guess your real data does not store numeric values in strings)
Num_df[['Inclusive', 'Exclusive']]= Num_df[['Inclusive', 'Exclusive']].astype('float32')
Actual_df[['Quantity', 'Rating']]=Actual_df[['Quantity', 'Rating']].astype('float32')
# define two helper functions (or just store the categories / variables in different dataframes)
def get_variable_data(df, variable):
df= df.loc[df['Variable'] == variable, ['Cats', 'Value']].copy()
df.set_index(['Cats'], inplace=True)
df.columns= [variable + '_value']
return df
def get_num_data(df, variable):
df= df.loc[df['Variable'] == variable, ['Inclusive', 'Value']].copy()
df.sort_values(['Inclusive'], inplace=True)
df.columns=[variable + '_inclusive', variable + '_value']
# join the first part by a regular join
Joined_df= Actual_df
for cat in ['Color', 'Fruit']:
Joined_df= Joined_df.merge(get_variable_data(Cat_df, cat), left_on=[cat], right_index=True, how='left')
# now join according ranges using asof
for cat in ['Quantity', 'Rating']:
print(cat)
Joined_df= pd.merge_asof(Joined_df, get_num_data(Num_df, cat), left_on=[cat], right_on='Inclusive', direction='backward', suffixes=['', '_'+cat])
# drop the excess columns
Joined_df.drop([col for col in Joined_df if col.endswith('_inclusive')], axis='columns', inplace=True)
# the result of this is
Color Fruit Quantity Rating Color_value Fruit_value Quantity_value Rating_value
0 yellow banana 4.0 0.5 -0.2836 0.3648 0.2145 -0.4378
如上所述, merge_asof
的最后一步假设您的范围不包含间隙,其中您没有值并跨越整个值范围。 因此,您无需检查范围的结尾。 但是,如果该假设不正确,则只需稍微更改代码即可:
merge_asof
原样使用merge_asof
,只需更改get_num_data
,因此它也返回Exclusive
列。
使用Join_df.loc[Joined_df[cat]>=Joined_df[cat + '_exclusive'], cat]=defaultvalue
删除超出排他范围的值。
顺便说一句,这样做真的很安全,因为如果有一行,其中cat
列的值所在,那么它会被merge_asof
选中,因为它会搜索最大的可用Inclusive
值,即较小或等于col
的值(我的意思是,至少如果您没有重叠范围,但对于您的示例中的星座来说,这似乎不太可能)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.