J'essaie d'insérer de nouvelles lignes dans un fichier Excel en utilisant un cadre de données pandas lorsqu'une colonne particulière a une condition spécifique
Par exemple:
Input
A B C D E
0 AA 111 2 2
1 CC 222 8 12
2 DD 333 3 3
Output
A B C D E (Output Column)
0 AA 111 2 2 111-2
1 CC 222 8 8 222-8
2 CC 222 9 9 222-9
3 CC 222 10 10 222-10
4 CC 222 11 11 222-11
5 CC 222 12 12 222-12
6 DD 333 3 3 333-3
Si vous voyez ici, les colonnes C et D ont une plage de 8 à 12 pour la ligne n ° 1. Je dois donc diviser la ligne en conséquence. Si C et D sont identiques, pas d'ajout de nouvelles lignes.
3 Réponses :
Mon exemple utilise pour obtenir des données à partir de lignes avec des valeurs différentes pour les colonnes C et D et créer de nouvelles données pour celles-ci. Ajoutez ensuite ces nouvelles données aux données sans aucune différence.
A B C D E 0 AA 111 2 2 111-2 1 DD 333 3 3 111-2 2 CC 222 8 8 222-8 3 CC 222 9 9 222-9 4 CC 222 10 10 222-10 5 CC 222 11 11 222-11 6 CC 222 12 12 222-12
Résultat:
import pandas as pd
# setup data
data_raw = [['AA', 111, 2, 2], ['CC', 222, 8, 12], ['DD', 333, 3, 3]]
data = pd.DataFrame(data_raw, columns=['A', 'B', 'C','D'])
# get items with no difference
rest_of_data = data.loc[data['C'] == data['D']]
# create value for E column
rest_of_data = rest_of_data.copy()
rest_of_data['E'] = str(str(rest_of_data['B'].values[0]) + '-' + str(rest_of_data['C'].values[0]))
# find items with difference
difference_data = data.loc[data['C'] != data['D']]
# get numbers of elements to create
start = int(difference_data['C'])
stop = int(difference_data['D'])
# create new data
create_data = []
for i in range(start,stop+1,1):
new = [difference_data['A'].values[0], difference_data['B'].values[0], i, i, str(difference_data['B'].values[0])+'-'+str(i)]
create_data.append(new)
new_data = pd.DataFrame(create_data, columns=['A', 'B', 'C','D', 'E'])
# concatenate frames
frames = [rest_of_data, new_data]
result = pd.concat(frames, ignore_index=True)
Une autre solution, utilisant Index .repeat pour créer le cadre de sortie, puis groupby.cumcount et str concaténation pour mettre à jour les valeurs des colonnes C , D et E:
A B C D E 0 AA 111 2 2 111-2 1 CC 222 8 8 222-8 1 CC 222 9 9 222-9 1 CC 222 10 10 222-10 1 CC 222 11 11 222-11 1 CC 222 12 12 222-12 2 DD 333 3 3 333-3
[out
df1 = df.loc[df.index.repeat((df.D - df.C).add(1))]
df1['C'] = df1['C'] + df1.groupby('A').cumcount()
df1['D'] = df1['C']
df1['E'] = df['B'].astype(str) + '-' + df1['C'].astype(str)
df = pd.DataFrame(
data={
'A': ['AA', 'CC', 'DD'],
'B': [111, 222, 333],
'C':[2, 8, 3],
'D':[2, 12, 3],
'E':[None, None, None],
}
)
new_df = pd.DataFrame(
data={
'A': [],
'B': [],
'C': [],
'D': [],
'E': [],
},
dtype=np.int64
)
for idx, row in df.iterrows():
if row['C'] == row['D']:
new_df = new_df.append(
pd.DataFrame(
data={
'A': [row['A']],
'B': [int(row['B'])],
'C': [int(row['C'])],
'D': [int(row['D'])],
'E': [str(row['B']) + '-' + str(row['D'])],
}
)
)
elif int(row['D']) > int(row['C']):
tmp_c = int(row['C'])
tmp_d = int(row['D'])
while tmp_d >= tmp_c:
new_df = new_df.append(
pd.DataFrame(
data={
'A': [row['A']],
'B': [int(row['B'])],
'C': [int(row['C'])],
'D': [tmp_c],
'E': [str(row['B']) + '-' + str(tmp_c)],
}
)
)
tmp_c += 1
print(new_df)