pandas Pyrthon脚本,用于根据两个不同列中相同行之间的匹配,计算同一列中的两行

xvw2m8pv  于 2023-02-28  发布在  其他
关注(0)|答案(3)|浏览(101)

我想创建一个Python脚本来计算一个新的列,基于从两个不同行的同一列中减去两个值。
用于计算的两行应该定义为与另外两列的值匹配。因此,要指定并给予一个示例:
| 身份证|标签|金额|
| - ------|- ------|- ------|
| 1个|第二章|三点七五|
| 第二章|某某|十五|
| 三个|四个|四个|
| 四个|某某|十四|
| 五个|六个|五个|
| 六个|某某|十五点五|
上表是我现在拥有的一个例子。
下表包含我要创建的列。对于我来说,“NaN或0”是在指定行还是在后面的行中并不重要:
| 身份证|标签|金额|新建列|
| - ------|- ------|- ------|- ------|
| 1个|第二章|三点七五|NaN或0,或仅为Amount中的值|
| 第二章|某某|十五|十一时二十五分|
| 三个|四个|四个|NaN或0,或仅为Amount中的值|
| 四个|某某|十四|十个|
| 五个|六个|五个|NaN或0,或仅为Amount中的值|
| 六个|某某|十五点五|十点五|
因此,这里第二行中NewColumn的值等于11.25,因为满足以下条件:

  • 列“Id”的值等于列“Tag”中的值。
  • 因此,NewColumn应采用行中较大数字的列“Amount”的值,并将其减去行中较小数字的值。
  • 这意味着计算结果为15-3.75 = 11.25。

为了给予一些上下文,第2行“金额”中的值包括增值税。同一列前面一行中的值是增值税本身。ID是事务处理ID,“标记”列用于将增值税事务处理与正确的相应完整事务处理链接在一起。
我已经尝试使用ChatGPT来解决这个问题,但似乎不能完全解决它。以下是我迄今为止:

import pandas as pd

# Load the dataset into a pandas dataframe
df = pd.read_csv('path/to/dataset.csv')

# Define the name of the column to fetch data from
other_column_name = 'other_column_name'

# Iterate over each row in the dataframe
for index, row in df.iterrows():
    # Fetch data from another row and column based on an exact match
    search_value = row['column_name']
    matching_row = df.loc[df['column_name'] == search_value]
    if len(matching_row) == 1:
        other_column_data = matching_row[other_column_name].values[0]
    else:
        other_column_data = None

    # Use the fetched data to calculate a new column
    if other_column_data is not None:
        new_column_data = row['existing_column'] + other_column_data
    else:
        new_column_data = None

    # Add the new column to the dataframe
    if new_column_data is not None:
        df.at[index, 'new_column'] = new_column_data

# Save the updated dataset to a new CSV file
df.to_csv('path/to/new_dataset.csv', index=False)

它只输出Tag和Id中的值的组合。

pwuypxnk

pwuypxnk1#

不要使用iterrows,而是使用矢量方法:

# identify rows with "xxx"
m = df['Tag'].ne('xxx')

# set up grouper for Tag and successive xxx
g = df.groupby(m.cumsum())['Amount'].transform

# assign difference on "xxx" rows
df.loc[~m, 'NewColumn'] = g('max')-g('min')

输出:

Id  Tag  Amount  NewColumn
0   1    2    3.75        NaN
1   2  xxx   15.00      11.25
2   3    4    4.00        NaN
3   4  xxx   14.00      10.00
4   5    6    5.00        NaN
5   6  xxx   15.50      10.50
如果"xxx"是变量字符串
# keep only numeric Tags
s = pd.to_numeric(df['Tag'], errors='coerce')

# set up grouper for Tag and successive ones
g = df.groupby(s.ffill())['Amount'].transform

# assign difference on non Tag rows
df.loc[s.isna(), 'NewColumn'] = g('max')-g('min')

示例:

Id  Tag  Amount  NewColumn
0   1    2    3.75        NaN
1   2  abc   15.00      11.25
2   3    4    4.00        NaN
3   4  def   14.00      10.00
4   5    6    5.00        NaN
5   6  ghi   15.50      10.50
aurhwmvo

aurhwmvo2#

由于我无法编辑我的问题,我想贡献与此更新,使我的第二个表可读性。
| 身份证|标签|金额|新建列|
| - ------|- ------|- ------|- ------|
| 1个|第二章|三点七五|NaN或0,或仅为Amount中的值|
| 第二章|某某|十五|十一时二十五分|
| 三个|四个|四个|NaN或0,或仅为Amount中的值|
| 四个|某某|十四|十个|
| 五个|六个|五个|NaN或0,或仅为Amount中的值|
| 六个|某某|十五点五|十点五|
我还要补充一点,我不能简单地对这些交易应用单一的增值税百分比,因为这些交易的增值税不同。
此外,也不期望这里出现“完美”关系,即对应的行将彼此紧接。

vwoqyblh

vwoqyblh3#

你的尝试接近真相:

import pandas as pd

df = pd.DataFrame({'Id': [1, 2, 3, 4, 5, 6],
                   'Tag': [2, 'xxx', 4, 'xxx', 6, 'xxx'],
                   'Amount': [3.75, 15, 4, 14, 5, 15.5]})

# create empty column for new values
df['NewColumn'] = None

for index, row in df.iterrows():
    if isinstance(row['Tag'], int):
        matching_row = df.loc[df['Id'] == row['Tag']]
        if not matching_row.empty:
            new_value = matching_row.iloc[0]['Amount'] - row['Amount']
            df.at[index, 'NewColumn'] = new_value

df['NewColumn'].fillna(0, inplace=True)
print(df)

退货

Id  Tag  Amount  NewColumn
0   1    2    3.75      11.25
1   2  xxx   15.00       0.00
2   3    4    4.00      10.00
3   4  xxx   14.00       0.00
4   5    6    5.00      10.50
5   6  xxx   15.50       0.00
    • 编辑**

如果最后一列的所有值都为0,这意味着ID是一个字符串,因此,我建议在应用该方法之前将它们转换为Int

import pandas as pd

df = pd.DataFrame({'Id': [1, 2, 3, 4, 5, 6],
                   'Tag': [2, 'xxx', 4, 'xxx', 6, 'xxx'],
                   'Amount': [3.75, 15, 4, 14, 5, 15.5]})
df['Id'] = df['Id'].astype(int)
print(df.info())
# create empty column for new values
df['NewColumn'] = None

for index, row in df.iterrows():
    if isinstance(row['Tag'], int):
        matching_row = df.loc[df['Id'] == row['Tag']]
        if not matching_row.empty:
            new_value = matching_row.iloc[0]['Amount'] - row['Amount']
            df.at[index, 'NewColumn'] = new_value

df['NewColumn'].fillna(0, inplace=True)
print(df.info())

这给了你你所期望的。你当然可以在之后把它们转换回字符串。

相关问题