Если вы просто достигнете желаемого ожидаемого результата, то может также применяться следующий код:
import pandas as pd
from io import StringIO
YOUR_TXT_DATA = """\
1|A|-1|10|100|1|2
1|A|2|20|35|2|3
1|B|1|15|5|3|5
2|B|5|23|25|4|2
2|B|2|33|20|22|98
2|D|4|23|21|20|32
"""
df = pd.read_csv(StringIO(YOUR_TXT_DATA), header=None,
usecols=[_ for _ in range(0, 5)],
names=['key1', 'key2', 'group', 'v1', 'v2'],
sep='|')
result_dict = dict(comboKey1=[], new_v1=[])
for key1, key2, group, v1, v2 in df.values:
key = str(key1) + '_' + str(key2)
if key not in result_dict['comboKey1']:
result_dict['comboKey1'].append(key)
result_dict['new_v1'].append({str(group): [v1, v2]})
else:
index = result_dict['comboKey1'].index(key)
result_dict['new_v1'][index].update({str(group): [v1, v2]})
result_df = pd.DataFrame.from_dict(result_dict)
print(result_df)
output
comboKey1 new_v1
0 1_A {'-1': [10, 100], '2': [20, 35]}
1 1_B {'1': [15, 5]}
2 2_B {'5': [23, 25], '2': [33, 20]}
3 2_D {'4': [23, 21]}
О данных теста
Я думаю, что есть некоторые особые случаи, которые вам, возможно, придется рассмотреть, если предположить, что данные выглядят следующим образом.
key1|key2|group|v1|v2|v3|v4
1|A|-1|10|100|1|2
1|A|-1|10|100|1|2
1|A|-1|20|35|2|3
каков ваш ожидаемый результат? (случай 1 ~ 3)
- случай 1: подлежит последнему.
1_A {'-1': [20, 35]}
(решение: dict) - дело 2: сохранить все, но не дублировать:
{('-1', (10, 100)), ('-1', (20, 35))}
(решение: установить) - дело 3: сохранить все
1_A [('-1', (10, 100)), ('-1', (10, 100)), ('-1', (20, 35))]
(решение: список)
код:
from unittest import TestCase
import pandas as pd
from io import StringIO
OTHER_TXT_DATA = """\
1|A|-1|10|100|1|2
1|A|-1|10|100|1|2
1|A|-1|20|35|2|3
"""
class MyTests(TestCase):
def __init__(self, *args, **options):
super().__init__(*args, **options)
self.df = pd.read_csv(StringIO(OTHER_TXT_DATA), header=None,
usecols=[_ for _ in range(0, 5)],
names=['key1', 'key2', 'group', 'v1', 'v2'],
sep='|')
def setUp(self) -> None:
# init on every test case.
self.result_dict = dict(comboKey1=[], new_v1=[])
def solution_base(self, new_v1_fun, update_v1_fun) -> pd.DataFrame:
result_dict = self.result_dict
for key1, key2, group, v1, v2 in self.df.values:
key = str(key1) + '_' + str(key2)
if key not in result_dict['comboKey1']:
result_dict['comboKey1'].append(key)
new_v1_fun(group, v1, v2) # result_dict['new_v1'].append({str(group): [v1, v2]})
else:
index = result_dict['comboKey1'].index(key)
update_v1_fun(index, group, v1, v2) # result_dict['new_v1'][index].update({str(group): [v1, v2]})
df = pd.DataFrame.from_dict(result_dict)
print(df)
return df
def test_case_1_dict(self):
df = self.solution_base(new_v1_fun=lambda group, v1, v2: self.result_dict['new_v1'].append({str(group): [v1, v2]}),
update_v1_fun=lambda index, group, v1, v2: self.result_dict['new_v1'][index].update({str(group): [v1, v2]}))
self.assertTrue(df.equals(pd.DataFrame(
columns=['comboKey1', 'new_v1'],
data=[
['1_A', {'-1': [20, 35]}],
]
)))
def test_case_2_set(self):
df = self.solution_base(new_v1_fun=lambda group, v1, v2: self.result_dict['new_v1'].append({(str(group), (v1, v2))}),
update_v1_fun=lambda index, group, v1, v2: self.result_dict['new_v1'][index].add((str(group), (v1, v2))))
self.assertTrue(df.equals(pd.DataFrame(
columns=['comboKey1', 'new_v1'],
data=[
['1_A', {('-1', (20, 35)), ('-1', (10, 100))}],
]
)))
def test_case_3_list(self):
df = self.solution_base(new_v1_fun=lambda group, v1, v2: self.result_dict['new_v1'].append([(str(group), (v1, v2))]),
update_v1_fun=lambda index, group, v1, v2: self.result_dict['new_v1'][index].append((str(group), (v1, v2))))
self.assertTrue(df.equals(pd.DataFrame(
columns=['comboKey1', 'new_v1'],
data=[
['1_A', [('-1', (10, 100)), ('-1', (10, 100)), ('-1', (20, 35))]],
]
)))
примечание: аннотация (см. PEP484 ) не поддерживается Python 2.