Reputation: 11512
I have this problem that I thought was a no-brainer, but I am apparently missing the logic behind passing arguments to a function. So, I have this dataframe,
id type zone d
0 1 a a1 23
1 1 a b1 45
2 1 a c1 23
3 2 a c1 56
4 2 b a1 7
5 2 b b1 5
6 3 b a1 2
7 3 b a1 9
8 3 b b1 43
9 4 c c1 21
10 4 c c1 67
11 5 c b1 34
12 5 c a1 21
13 1 a a1 3
14 1 a b1 4
15 1 a c1 12
16 2 a c1 10
17 2 b a1 33
18 2 b b1 22
19 3 b a1 334
20 3 b a1 22
21 3 b b1 11
22 4 c c1 55
23 4 c c1 88
24 5 c b1 22
25 5 c a1 9
(here it is in the form of a dict:
{'id': {0: 1,
1: 1,
2: 1,
3: 2,
4: 2,
5: 2,
6: 3,
7: 3,
8: 3,
9: 4,
10: 4,
11: 5,
12: 5,
13: 1,
14: 1,
15: 1,
16: 2,
17: 2,
18: 2,
19: 3,
20: 3,
21: 3,
22: 4,
23: 4,
24: 5,
25: 5},
'type': {0: 'a',
1: 'a',
2: 'a',
3: 'a',
4: 'b',
5: 'b',
6: 'b',
7: 'b',
8: 'b',
9: 'c',
10: 'c',
11: 'c',
12: 'c',
13: 'a',
14: 'a',
15: 'a',
16: 'a',
17: 'b',
18: 'b',
19: 'b',
20: 'b',
21: 'b',
22: 'c',
23: 'c',
24: 'c',
25: 'c'},
'zone': {0: 'a1',
1: 'b1',
2: 'c1',
3: 'c1',
4: 'a1',
5: 'b1',
6: 'a1',
7: 'a1',
8: 'b1',
9: 'c1',
10: 'c1',
11: 'b1',
12: 'a1',
13: 'a1',
14: 'b1',
15: 'c1',
16: 'c1',
17: 'a1',
18: 'b1',
19: 'a1',
20: 'a1',
21: 'b1',
22: 'c1',
23: 'c1',
24: 'b1',
25: 'a1'},
'd': {0: 23,
1: 45,
2: 23,
3: 56,
4: 7,
5: 5,
6: 2,
7: 9,
8: 43,
9: 21,
10: 67,
11: 34,
12: 21,
13: 3,
14: 4,
15: 12,
16: 10,
17: 33,
18: 22,
19: 334,
20: 22,
21: 11,
22: 55,
23: 88,
24: 22,
25: 9}}
I also have two lists
A = ['a','b','c']
B = ['a1','b1','c1']
which are the unique type
and zone
in the dataframe df_test
. Now, I've creates a function that will return histogram for the "accuracy" of measurements for all types to type
. Ignore the fact that the function in itself makes no sense with the provided data, it does return exactly what I want with real data.
df_accuracy =[]
def Accuracy_by_id_for_type(distance, df, types):
df_region = df[df['type']=="{}".format(type)]
id_dist = df_region.drop_duplicates()
id_s = id_dist[id_dist['d'].notna()]
id_sm = id_s.loc[id_s.groupby('id', sort=False)['d'].idxmin()]
max_dist = id_sm['d'].max()
min_dist = id_sm['d'].min()
id_sm['normalized_dist'] = (id_sm['d'] - min_dist) / (max_dist - min_dist)
id_sm['accuracy'] = round((1-id_sm['normalized_dist'])*100,1)
df_accuracy.append(id_sm)
id_sm = id_sm.sort_values('accuracy',ascending=False)
id_sm.hist()
plt.suptitle("Accuracy for {} ".format(type))
plt.show(block=True)
plt.show(block=True)
I pass every type
in the following way:
for types in A:
Accuracy_by_id_for_type(1, df_test,"{}".format(types))
and it returns as many histograms as there are types.
A similar function exists for zone
in the list B
.
Now, to my issues:
I have created the following function to deal with both types and zone, i.e. "do the same thing" for all combinations of elements in A
and B
:
df_accuracy_type_zone = []
def Accuracy_by_id_for_type_zone(distance, df, types, zone):
df_region = df[(df['type']=="{}".format(types)) & (df['type']=="{}".format(zone))]
id_dist = df_region.drop_duplicates()
id_s = id_dist[id_dist['d'].notna()]
id_sm = id_s.loc[id_s.groupby('id', sort=False)['d'].idxmin()]
max_dist = id_sm['d'].max()
min_dist = id_sm['d'].min()
id_sm['normalized_dist'] = (id_sm['d'] - min_dist) / (max_dist - min_dist)
id_sm['accuracy'] = round((1-id_sm['normalized_dist'])*100,1)
df_accuracy_type_zone.append(id_sm)
id_sm = id_sm.sort_values('accuracy',ascending=False)
id_sm.hist()
plt.suptitle("Accuracy for {} and zone {}".format(types).format(zone))
plt.show(block=True)
plt.show(block=True)
As you can see:
df_region = df[(df['type']=="{}".format(types)) & (df['type']=="{}".format(zone))]
keeps only the data in the dataframe for one type and one zone. What I tried was this:
for types in A:
for zone in B:
Accuracy_by_id_for_type_zone(1, df_test, "{}".format(types), "{}".format(zone))
but I get the error:
IndexError: Replacement index 1 out of range for positional args tuple
What am I doing wrong? Thankful for any insight.
Upvotes: 0
Views: 68
Reputation: 120509
You have to replace:
plt.suptitle("Accuracy for {} and zone {}".format(types).format(zone))
by:
plt.suptitle("Accuracy for {} and zone {}".format(types, zone))
or better:
plt.suptitle(f"Accuracy for {types} and zone {zone}")
To know more about f-strings
, refer to the documentation
Upvotes: 1