如何从 pandas 中的重复行中累积单个单元格
How to accumulate single cells from repeated rows in pandas
这是我的第一个 post,在遇到一些问题后,我修复了它们。
重点是,我有一个我想修改的 CSV,仅在重复下一行时才重新定位一个单元格,以便仅在一行中累积重复值的值。如果您想重复多次使用它,则必须执行相同的次数。如果有人能改进一下,那也太棒了。
import pandas as pd
#df = pd.read_csv('MyCSV.csv', sep='\t', index_col=False, header=0)
#In my case, csv didn't work because of settings from read_csv
#Which looks like next serie:
data = [['LINF_01000000', 'LINJ.1:11111:222222:-', 'N/A', 'N/A', 'N/A'], ['LINF_01000000', 'LINJ.1:122222:333333:-', 'N/A', 'N/A', 'N/A'], ['LINF_01000000', 'N/A', 'N/A', 'N/A', 'N/A'], ['LINF_02000000', 'LINJ.1:10011:2211122:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:14441:666222:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:77435:2543522:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:544351:22543542:-', 'N/A', 'N/A', 'N/A']]
# Create the pandas DataFrame
df = pd.DataFrame(data, columns = ['LINF_MIX', 'Accession', 'Accession2', 'Accession3', 'Accession4'])
#and then start my script here to execute:
column0 = df.iloc[:, 0]
index_Linf_Rep = 2
for LINF in column0:
index_Linf = index_Linf_Rep - 1
LINF = df.iloc[index_Linf, 0]
LINF_Rep = df.iloc[index_Linf_Rep, 0]
if LINF == LINF_Rep:
coordenada_repet = df.iloc[index_Linf_Rep, 1]
coordenada_repet2 = df.iloc[index_Linf_Rep, 2]
coordenada_repet3 = df.iloc[index_Linf_Rep, 3]
coordenada_repet4 = df.iloc[index_Linf_Rep, 4]
coordenada_repet5 = df.iloc[index_Linf_Rep, 5]
coordenada_intr = df.iloc[index_Linf, 2]
coordenada_intr2 = df.iloc[index_Linf, 3]
coordenada_intr3 = df.iloc[index_Linf, 4]
coordenada_intr4 = df.iloc[index_Linf, 5]
coordenada_intr5 = df.iloc[index_Linf, 6]
df.iat[index_Linf, 2] = coordenada_repet
print("Hay matches")
if coordenada_intr == coordenada_repet:
df.iat[index_Linf, 3] = coordenada_repet2
elif coordenada_intr2 == coordenada_repet2:
df.iat[index_Linf, 4] = coordenada_repet3
elif coordenada_intr3 == coordenada_repet3:
df.iat[index_Linf, 5] = coordenada_repet4
print(LINF + ' se ha repetido 4 veces')
elif coordenada_intr4 == coordenada_repet4:
df.iat[index_Linf, 6] = coordenada_repet5
print(LINF + ' se ha repetido 5 veces')
else:
print('No hay match en estos dos LINF: ')
print(LINF + ' ' + LINF_Rep)
index_Linf_Rep += 1
if index_Linf_Rep == 9427:
break
#
df.to_csv('MyCSV.csv', index=False)
谢谢。
我不明白你想要完成什么。您是要删除重复的行还是要将它们加在一起/连接字符串。
这也有点令人困惑,因为这里:
coordenada_repet = df.iloc[index_ni, 1]
coordenada_intr = df.iloc[index_i, 2]
你得到的是第二行第二列的值,然后是第一行第三列的值,我不知道这是否适合你。
我鼓励您查看 pandas.Series.fill (method="ffill")、pandas.DataFrame.where(或 np.where)和 pandas.Series.shift
您可以结合使用创建一个移动一行的列并循环遍历原始数据并移动以获得重复的值。
无论如何,我相信 df.at 函数采用这样的方括号:
df.at[index_name, column_name]
df.iat 函数如下所示:
df.iat[index_index,column_index]
At reference here and iat reference here
在您的代码中,您使用的是 at(),因此可以尝试调整它。请让我知道我上面的问题,因为可能有更简单的解决方案
编辑:向量化代码
df_shifted = df.shift(-1)
new_df = df.copy()
new_df["Accession2"] = np.where(df["LINF_MIX"] ==
df_shifted["LINF_MIX"], df_shifted["Accession"], df["Accession2"])
new_df["Accession4"] = np.where((df["Accession2"] == "N/A") &
(["Accession3"] != "N/A"), df_shifted["Accession3"], df["Accession4"])
new_df["Accession4"] = new_df["Accession4"].fillna("N/A")
new_df["Accession3"] = np.where(df["Accession2"] != "N/A", df_shifted["Accession2"], df["Accession2"])
df.equals(new_df)
你可以试试矢量化代码。根据您发布的错误消息,我认为错误来自数据类型错误的列之一。那或者你正在尝试使用某处的字符串访问 iloc。
这是我的第一个 post,在遇到一些问题后,我修复了它们。 重点是,我有一个我想修改的 CSV,仅在重复下一行时才重新定位一个单元格,以便仅在一行中累积重复值的值。如果您想重复多次使用它,则必须执行相同的次数。如果有人能改进一下,那也太棒了。
import pandas as pd
#df = pd.read_csv('MyCSV.csv', sep='\t', index_col=False, header=0)
#In my case, csv didn't work because of settings from read_csv
#Which looks like next serie:
data = [['LINF_01000000', 'LINJ.1:11111:222222:-', 'N/A', 'N/A', 'N/A'], ['LINF_01000000', 'LINJ.1:122222:333333:-', 'N/A', 'N/A', 'N/A'], ['LINF_01000000', 'N/A', 'N/A', 'N/A', 'N/A'], ['LINF_02000000', 'LINJ.1:10011:2211122:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:14441:666222:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:77435:2543522:-', 'N/A', 'N/A', 'N/A'], ['LINF_03000000', 'LINJ.1:544351:22543542:-', 'N/A', 'N/A', 'N/A']]
# Create the pandas DataFrame
df = pd.DataFrame(data, columns = ['LINF_MIX', 'Accession', 'Accession2', 'Accession3', 'Accession4'])
#and then start my script here to execute:
column0 = df.iloc[:, 0]
index_Linf_Rep = 2
for LINF in column0:
index_Linf = index_Linf_Rep - 1
LINF = df.iloc[index_Linf, 0]
LINF_Rep = df.iloc[index_Linf_Rep, 0]
if LINF == LINF_Rep:
coordenada_repet = df.iloc[index_Linf_Rep, 1]
coordenada_repet2 = df.iloc[index_Linf_Rep, 2]
coordenada_repet3 = df.iloc[index_Linf_Rep, 3]
coordenada_repet4 = df.iloc[index_Linf_Rep, 4]
coordenada_repet5 = df.iloc[index_Linf_Rep, 5]
coordenada_intr = df.iloc[index_Linf, 2]
coordenada_intr2 = df.iloc[index_Linf, 3]
coordenada_intr3 = df.iloc[index_Linf, 4]
coordenada_intr4 = df.iloc[index_Linf, 5]
coordenada_intr5 = df.iloc[index_Linf, 6]
df.iat[index_Linf, 2] = coordenada_repet
print("Hay matches")
if coordenada_intr == coordenada_repet:
df.iat[index_Linf, 3] = coordenada_repet2
elif coordenada_intr2 == coordenada_repet2:
df.iat[index_Linf, 4] = coordenada_repet3
elif coordenada_intr3 == coordenada_repet3:
df.iat[index_Linf, 5] = coordenada_repet4
print(LINF + ' se ha repetido 4 veces')
elif coordenada_intr4 == coordenada_repet4:
df.iat[index_Linf, 6] = coordenada_repet5
print(LINF + ' se ha repetido 5 veces')
else:
print('No hay match en estos dos LINF: ')
print(LINF + ' ' + LINF_Rep)
index_Linf_Rep += 1
if index_Linf_Rep == 9427:
break
#
df.to_csv('MyCSV.csv', index=False)
谢谢。
我不明白你想要完成什么。您是要删除重复的行还是要将它们加在一起/连接字符串。
这也有点令人困惑,因为这里:
coordenada_repet = df.iloc[index_ni, 1]
coordenada_intr = df.iloc[index_i, 2]
你得到的是第二行第二列的值,然后是第一行第三列的值,我不知道这是否适合你。 我鼓励您查看 pandas.Series.fill (method="ffill")、pandas.DataFrame.where(或 np.where)和 pandas.Series.shift
您可以结合使用创建一个移动一行的列并循环遍历原始数据并移动以获得重复的值。
无论如何,我相信 df.at 函数采用这样的方括号:
df.at[index_name, column_name]
df.iat 函数如下所示:
df.iat[index_index,column_index]
At reference here and iat reference here
在您的代码中,您使用的是 at(),因此可以尝试调整它。请让我知道我上面的问题,因为可能有更简单的解决方案
编辑:向量化代码
df_shifted = df.shift(-1)
new_df = df.copy()
new_df["Accession2"] = np.where(df["LINF_MIX"] ==
df_shifted["LINF_MIX"], df_shifted["Accession"], df["Accession2"])
new_df["Accession4"] = np.where((df["Accession2"] == "N/A") &
(["Accession3"] != "N/A"), df_shifted["Accession3"], df["Accession4"])
new_df["Accession4"] = new_df["Accession4"].fillna("N/A")
new_df["Accession3"] = np.where(df["Accession2"] != "N/A", df_shifted["Accession2"], df["Accession2"])
df.equals(new_df)
你可以试试矢量化代码。根据您发布的错误消息,我认为错误来自数据类型错误的列之一。那或者你正在尝试使用某处的字符串访问 iloc。