对不起,如果以前有人问过这个问题(我只能找到对前面的行有效的方法,而不是数据帧的其余部分).

我目前正试图将我的迭代方法转换为对Pandas (和时间)更友好的版本.问题如下:我有两列,"A"和"B",它们都是球员.每一次,"A"和"B"都具有不同的任意值.我想添加第三列,该列的值为"A WINS!"或者"B赢了!"基于该行的值下面的行.

来决定什么时候‘A获胜!’对于某个行号,我想将该行"A"列中的值与该行下面的"B"列中的每个值进行比较.为了确定什么时候‘B获胜!’,我想做同样的事情:获取行"B"中的值,并将其与该条目下面的列"A"中的每个条目进行比较.最先与另一列中的值"匹配"的将是胜利者.下面是一个例子:

Time A B Winner
1 2 4 A wins!
2 3 5 B wins!
3 5 2 A wins!
4 6 5 None
5 2 10 B wins!
6 10 7 None

在时间1,A获胜,因为在时间3,"B"在"A"可以取值4之前取值2.在时间2,"B"取胜,因为下面一行中的"A"取值5,而"B"取值3.时间3和5类似,在时间4和时间6,没有赢家,因为在后面的回合中,对手的牌手不会碰巧相互取值.

现在,我只需使用df.iterrow()就有了一个有效的解决方案.我有一个相当大的数据集,所以我想加快速度,但我想不出任何简单的Panda函数,因为它们通常是逐行隔离的.由于对行的依赖,我所有的Apply和maptry 都没有奏效,所以我正在寻找一种可能减少时间且不必使用显式迭代的解决方案.感谢任何人的帮助,谢谢!

编辑:这是我的工作迭代解决方案.我向findwinner提供了一个DataFrame,它对每一行调用findwinner_row.

def find_winner_row(df, row, result):
    A_val = df['A'][row] # Player A
    B_val = df['B'][row] # Player B
    potentials_B = np.where(df['A'][row+1:] == B_val)[0] #[row+1:] slices and only considers the future values of A
    potentials_A = np.where(df['B'][row+1:] == A_val)[0]
    # below logic is just to handle the case when there are no matching values
    if potentials_B.size == 0:
        B_switch_time = len(df.columns) + 1
    else:
        B_switch_time = potentials_B[0]
    if potentials_A.size == 0:
        A_switch_time = len(df.columns) + 1
    else:
        A_switch_time = potentials_A[0]
    # now which is first?
    if B_switch_time < A_switch_time:
        result[row] = "B"
    elif B_switch_time > A_switch_time:
        result[row] = "A"
    else:
        result[row] = "None"
    
def find_winner(df):
    result_series = pd.Series(np.zeros(len(df.columns)))
    for num, (index, row) in enumerate(df.iterrows()):
        find_winner_row(df, num, result_series)
    df.loc[:,'Winner'] = result_series.values
    return df
## So with our given example above, we can run the following and see we get the expected result
demo_df = pd.DataFrame([[2,4],[3,5],[5,2],[6,5],[2,10],[10,7]],columns=['A','B'])
find_winner(demo_df)

推荐答案

在添加代码之前就开始编写这篇文章--但我认为它可能仍然有帮助.我能够编写1个函数,该函数根据逻辑返回一个基于行索引的获胜者字符串,并以最少的(内部)迭代给出DataFrame:

# Sample data
import pandas as pd
data = {"Time":[1,2,3,4,5,6],"A":[2,3,5,6,2,10],"B":[4,5,2,5,10,7],"Winner":["A","B","A","None","B","None"]}
df = pd.DataFrame(data)

def FindWinner(row_index,dataframe=df):
    # Record the intial value in indicated column
    A_initial = df.iloc[row_index]["A"]
    B_initial  = df.iloc[row_index]["B"]

    # Convert data underneath this row into a pair of lists
    rowsUnderA = list(df.iloc[row_index+1:]["A"])
    rowsUnderB = list(df.iloc[row_index+1:]["B"])
    
    # Use .index() to find when the inital value appears next in the other list
    try: rowsUntilA_initial = rowsUnderB.index(A_initial)
    except ValueError: rowsUntilA_initial = "DOES_NOT_APPEAR"

    try: rowsUntilB_initial = rowsUnderA.index(B_initial)
    except ValueError: rowsUntilB_initial = "DOES_NOT_APPEAR"

    # Set win conditions--> first handle scenarios where one or both values do not appear
    if rowsUntilB_initial == "DOES_NOT_APPEAR" and rowsUntilA_initial == "DOES_NOT_APPEAR":
    return "No one wins :("

    elif rowsUntilB_initial == "DOES_NOT_APPEAR" and rowsUntilA_initial != "DOES_NOT_APPEAR":
    return "A wins!"
    
    elif rowsUntilB_initial != "DOES_NOT_APPEAR" and rowsUntilA_initial == "DOES_NOT_APPEAR":
    return "B wins!"
 
    # If A appears first, A wins ... vice versa
    elif rowsUntilA_initial < rowsUntilB_initial: return "A wins!"

    elif rowsUntilB_initial < rowsUntilA_initial: return "B wins!"

    # What if they are the same?
    elif rowsUntilB_initial == rowsUntilB_initial: return "... what happens if they're the same?"

Based on a quick test this does return the expected output: enter image description here

使用该函数应该可以创建/映射一个新列,甚至可以遍历每行一次并创建一个新列(这就是map无论如何都要做的事情).我理解这里的目标是最小化迭代,但没有以某种能力单独引用每一行-我不确定是否有一种方法来计算和显示获胜者.这里的逻辑与您的示例代码中的逻辑看起来很相似,但我想知道差异是否会影响运行时.我无法访问您的数据集,因此我自己无法确定这一点,但我认为无论如何都值得一试.

Python相关问答推荐

根据另一列中的nan重置值后重新加权Pandas列

为什么带有dropna=False的groupby会阻止后续的MultiIndex.dropna()工作?

如何记录脚本输出

PMMLPipeline._ fit()需要2到3个位置参数,但给出了4个位置参数

如何更改分组条形图中条形图的 colored颜色 ?

NumPy中条件嵌套for循环的向量化

UNIQUE约束失败:customuser. username

Python列表不会在条件while循环中正确随机化'

什么是合并两个embrame的最佳方法,其中一个有日期范围,另一个有日期没有任何共享列?

如何在FastAPI中为我上传的json文件提供索引ID?

为什么\b在这个正则表达式中不解释为反斜杠

python中csv. Dictreader. fieldname的类型是什么?'

Python避免mypy在相互引用中从另一个类重定义类时失败

如何在Gekko中使用分层条件约束

BeautifulSoup:超过24个字符(从a到z)的迭代失败:降低了首次深入了解数据集的复杂性:

Python:从目录内的文件导入目录

是否需要依赖反转来确保呼叫方和被呼叫方之间的分离?

按列表分组到新列中

组颠倒大Pandas 数据帧

为什么这个正则表达式没有捕获最后一次输入?