我已经创建了2个Pandas数据帧,如果行基于2个列变量匹配,我需要将DF1中的每一行与DF2中的每一行进行比较.基本上,我需要将DF2中的每一行与DF1中的第一行进行比较;将DF2中的每一行与DF1中的第二行进行比较,以此类推,如果它们具有相同的参与者编号和相同的试验编号.

通过"比较",我的意思是我每次都需要执行一次计算,然后如果结果值小于一个特定的数字,我需要知道我们在DF2的哪一行,并将其记录在一个新的列中.

我对Pandas 非常陌生,所以我不太确定从哪里开始,但我已经在下面详细介绍了我的问题的逐步逻辑.

以下是我的两个数据帧(样本--实际数据帧将非常大;每个数据帧超过10,000行):

DF1:

IP_INDEX IP_LABEL PARTICIPANT TRIAL CURRENT_FIX_INDEX PRE_FIX_X PRE_FIX_Y
1 1st 3 Seconds a 1 1 550 150
1 1st 3 Seconds a 1 2 600 300
1 1st 3 Seconds a 2 1 250 600
1 1st 3 Seconds b 1 1 400 400
1 1st 3 Seconds b 2 1 600 400

DF2:

IP_INDEX IP_LABEL PARTICIPANT TRIAL CURRENT_FIX_INDEX POST_FIX_X POST_FIX_Y
2 2nd 3 Seconds a 1 1 500 200
2 2nd 3 Seconds a 1 2 650 350
2 2nd 3 Seconds a 2 1 300 650
2 2nd 3 Seconds b 1 1 250 700
2 2nd 3 Seconds b 1 2 450 150
2 2nd 3 Seconds b 2 1 550 350
2 2nd 3 Seconds b 2 2 350 550

以下是将我的2个CSV文件导入到这些数据帧中的代码:

import pandas as pd
import os, math
import numpy as np

#change directory to where the file is
mycsvdir = os.chdir('C:/Users/Elisabeth/Desktop/Test/Output/CSV/')

#import csv file into dataframe
df1 = pd.read_csv('1st 3 Seconds.csv')
df2 = pd.read_csv('2nd 3 Seconds Full.csv')

从编程的Angular 来看,这基本上就是我迷路的地方.从逻辑的Angular 来看,以下是我需要的(任何给定行的示例):

A.在df1中创建一个名为‘refix’的新列.此字段目前为空,但稍后将根据下面的公式填充单元格. B.如果DF2‘Participant’=DF1‘Participant and DF2’Trial‘=DF1’Trial‘,则计算math.dist(p,q),其中p和q由DF1和DF2的*_FIX_X和*_FIX_Y值定义(**代表基于DF1或DF2的Pre或Post). B.2.如果DF2‘Participant’!=DF1‘Participant’or DF2‘Trial’!=DF1‘Trial’,则移至DF2中的下一行 C.如果math.dist(p,q)<的结果=150,则用DF2中的CURRENT_FIX_INDEX(我们在DF2中所在行)的值填充DF1中的‘REFIX’列(对于我们在DF1中所在的行). D.将DF1另存为新的CSV文件

我不确定我在这里是否正确,但以下是我用来确定math.dist(p,q)函数的p和q值的方法:

#define p and q values for distance calculation
p = [(df1['PRE_FIX_X']), (df1['PRE_FIX_Y'])]
q = [(df2['POST_FIX_X']), (df2['POST_FIX_Y'])]

根据给定的示例数据帧,完整的DF1文件如下所示:

IP_INDEX IP_LABEL PARTICIPANT TRIAL CURRENT_FIX_INDEX PRE_FIX_X PRE_FIX_Y REFIX
1 1st 3 Seconds a 1 1 550 150 1
1 1st 3 Seconds a 1 2 600 300 1,2
1 1st 3 Seconds a 2 1 250 600 1
1 1st 3 Seconds b 1 1 400 400
1 1st 3 Seconds b 2 1 600 400 1

推荐答案

EDITED: Now includes count of REFIXes per trial as requested in comments

你的问题看起来很复杂,有点难以理解,但我想这可能是你想要的?

我不认为使用嵌套的if语句迭代两个df语句是最有效的方法,但我现在想不出更好的 Select :)

第1部分:加载您提供的数据:(您显然可以忽略这一点,但为了便于重现/测试,将其放入:

import pandas as pd

# Define the data for DF1
data_df1 = {
    'IP_INDEX': [1, 1, 1, 1, 1],
    'IP_LABEL': ['1st 3 Seconds', '1st 3 Seconds', '1st 3 Seconds', '1st 3 Seconds', '1st 3 Seconds'],
    'PARTICIPANT': ['a', 'a', 'a', 'b', 'b'],
    'TRIAL': [1, 1, 2, 1, 2],
    'CURRENT_FIX_INDEX': [1, 2, 1, 1, 1],
    'PRE_FIX_X': [550, 600, 250, 400, 600],
    'PRE_FIX_Y': [150, 300, 600, 400, 400]
}

# Create DF1
df1 = pd.DataFrame(data_df1)

data_df2 = {
    'IP_INDEX': [2, 2, 2, 2, 2, 2, 2],
    'IP_LABEL': ['2nd 3 Seconds', '2nd 3 Seconds', '2nd 3 Seconds', '2nd 3 Seconds', '2nd 3 Seconds', '2nd 3 Seconds', '2nd 3 Seconds'],
    'PARTICIPANT': ['a', 'a', 'a', 'b', 'b', 'b', 'b'],
    'TRIAL': [1, 1, 2, 1, 1, 2, 2],
    'CURRENT_FIX_INDEX': [1, 2, 1, 1, 2, 1, 2],
    'POST_FIX_X': [500, 650, 300, 250, 450, 550, 350],
    'POST_FIX_Y': [200, 350, 650, 700, 150, 350, 550]
}

# Create DF2
df2 = pd.DataFrame(data_df2)

第2部分:进行计算:

import math

#Create function to calculate distance between coordinates
def calculate_distance(df1_row,df2_row):
    p = (df1_row['PRE_FIX_X'], df1_row['PRE_FIX_Y'])
    q = (df2_row['POST_FIX_X'], df2_row['POST_FIX_Y'])
    return math.dist(p, q)

refix_values = [] #Create empty list to hold lists of matching FIX_INDEX values in df2

for index, df1_row in df1.iterrows(): #Iterate through each row in df1
    fix_index_list = [] #Create empty list to hold matching INDEX values for loop row
    df2_subset = df2.loc[(df2['PARTICIPANT'] == df1_row['PARTICIPANT']) & (df2['TRIAL'] == df1_row['TRIAL'])] #Subset out matching data in df2 so we're not looping through the entirety of df2
    for i, df2_row in df2_subset.iterrows(): #Iterate through df2 subset
        dist = calculate_distance(df1_row,df2_row) #Calculate dist for each row
        if dist <= 150:
            fix_index_list.append(df2_row['CURRENT_FIX_INDEX']) #Add dist to list if greater or equal to 150
    refix_values.append(','.join(map(str, fix_index_list))) #Add list of matching INDEX values to list of lists

df1['REFIX'] = refix_values #Convert list of lists to new column

def count_refix_items(row_refix_value):
    integers = [int(s) for s in row_refix_value.split(',') if s.isdigit()] #Split string by commas and count resultant elements
    return len(integers)

refix_per_trial = df1[df1['REFIX'].notna()].groupby(['TRIAL','PARTICIPANT'])['REFIX'].apply(lambda x: x.apply(count_refix_items).sum()).reset_index()
refix_per_trial = refix_per_trial.rename(columns={'REFIX': 'REFIXes/trial/participant'}) #Rename column

df1 = pd.merge(df1, refix_per_trial, on = ['TRIAL','PARTICIPANT'], how = 'outer')

#Write df to csv
df1.to_csv('REFIX_calc_output.tab', sep='\t', index=False) #Change name of file to whatever you want

我使用您提供的输入获得的输出:

IP_INDEX IP_LABEL PARTICIPANT TRIAL CURRENT_FIX_INDEX PRE_FIX_X PRE_FIX_Y REFIX REFIXes/trial/participant
1 1st 3 Seconds a 1 1 550 150 1 3
1 1st 3 Seconds a 1 2 600 300 1,2 3
1 1st 3 Seconds a 2 1 250 600 1 1
1 1st 3 Seconds b 1 1 400 400 0
1 1st 3 Seconds b 2 1 600 400 1 1

Python-3.x相关问答推荐

模型中的__str__方法在Django管理面板中生成大量重复查询

如何转换Pandas中的数据,以使我 Select 的列名变为行值并增加行?

如何获得大Pandas 的常见时间间隔

小部件padx和包方法ipadx有什么不同?

如何使用魔杖扭曲图像

如何定义部署用 Python 编写的 Firestore 第二代函数的区域/位置?

类变量的Python子类被视为类方法

在不使用 split 函数的情况下从字符串中分割逗号(','),句号('.')和空格(' '),将字符串的单词附加到列表中

torch.stack([t1, t1, t1], dim=1)与torch.hstack([t1, t1, t1])之间有什么区别?

在 string.find() 条件下加入两个 Dataframes

隐藏Cartopy中高纬度非矩形投影的右侧轴(纬度)标签

如何转置和 Pandas DataFrame 并命名新列?

attrs 将 list[str] 转换为 list[float]

使用 GEKKO 使用代码解决最佳时间控制问题时出现 IndexError

是否有与 Laravel 4 等效的 python?

在python中,如果一个函数没有return语句,它会返回什么?

python 3的蓝牙库

try 在 Windows 10 高 DPI 显示器上解决模糊的 tkinter 文本 + zoom ,但担心我的方法不是 Pythonic 或不安全

SQLAlchemy:如果不存在则创建模式

如何在 Python 3.4 中使用 pip 3?