Используйте unstack
для изменения формы, поэтому возможно деление на строки, последнее изменение формы назад на stack
.
Последний для правильного упорядочения использовать swaplevel
, sort_index
и последний reindex
.
df1 = df.unstack(0)
df1.loc['% Completed', :] = df1.loc['Complete', :] / df1.loc['Total', :]
vals = ['Complete','Total','% Completed']
df1 = df1.stack().swaplevel(0,1).sort_index().reindex(vals, level=1)
print (df1)
June July August September
Tasks Des
A Complete 33.000000 10.000000 0.000000 0.000000
Total 181.000000 85.000000 69.000000 15.000000
% Completed 0.182320 0.117647 0.000000 0.000000
B Complete 5.000000 9.000000 0.000000 1.000000
Total 13.000000 12.000000 5.000000 1.000000
% Completed 0.384615 0.750000 0.000000 1.000000
C Complete 66.000000 54.000000 27.000000 12.000000
Total 137.000000 89.000000 78.000000 22.000000
% Completed 0.481752 0.606742 0.346154 0.545455
D Complete 451.000000 127.000000 87.000000 28.000000
Total 629.000000 203.000000 174.000000 51.000000
% Completed 0.717011 0.625616 0.500000 0.549020
E Complete 46.000000 27.000000 29.000000 2.000000
Total 135.000000 100.000000 86.000000 24.000000
% Completed 0.340741 0.270000 0.337209 0.083333
Другое решение с выбором DataFrame.xs
, делением и созданием уровня MultiIndex
по assign
и set_index
:
df1 = (df.xs('Complete', level=1)
.div(df.xs('Total', level=1))
.assign(Des='% Completed')
.set_index('Des', append=True)
)
vals = ['Complete','Total','% Completed']
df1 = df.append(df1).sort_index().reindex(vals, level=1)
Для загрузки пользовательских объектов в массиве это - то, что я раньше захватывал массив:
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
objectArray = [[NSMutableArray alloc] init];
}
необходимо проверить, что данные, возвращенные из пользовательских значений по умолчанию, не являются нолем, потому что я полагаю, что разархивирование от ноля вызывает катастрофический отказ.
Архивация проста, с помощью следующего кода:
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"];
Как f3lix указанный, необходимо заставить пользовательский объект соответствовать протоколу NSCoding. Добавление методов как следующее должно добиться цели:
- (void)encodeWithCoder:(NSCoder *)coder;
{
[coder encodeObject:label forKey:@"label"];
[coder encodeInteger:numberID forKey:@"numberID"];
}
- (id)initWithCoder:(NSCoder *)coder;
{
self = [super init];
if (self != nil)
{
label = [[coder decodeObjectForKey:@"label"] retain];
numberID = [[coder decodeIntegerForKey:@"numberID"] retain];
}
return self;
}
Я думаю, что похоже, что проблема с Вашим кодом не сохраняет массив результатов. Его загрузка данных пытается использовать
lastResults = [prefs arrayForKey:@"lastResults"];
, Это возвратит массив, указанный ключом.
См., "Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK?" (, Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK? )
<час>, Если Вы хотите к (de), сериализируют пользовательские объекты, необходимо обеспечить, функции к (de) сериализируют данные (протокол NSCoding). Решение, которое Вы отсылаете к работам с международным массивом, потому что массив не является объектом, а непрерывным блоком памяти.
Я рекомендовал бы против попытки сохранить материал как это в дб значений по умолчанию.
SQLite довольно легко взять и использовать. У меня есть эпизод в одном из моих скринкастов ( http://pragprog.com/screencasts/v-bdiphone ) о простой обертке, которую я записал (можно получить код, не покупая SC).
Это намного более чисто, чтобы хранить данные приложения в пространстве приложения.
Все, что сказало, имеет ли все еще смысл помещать эти данные в дб значений по умолчанию, затем см. сообщение f3lix отправленный.
Я думаю, что вы получили ошибку в вашем методе initWithCoder, по крайней мере в предоставленном коде, который вы не возвращаете «Я» объект.
- (id) initWithCoder: (NSCoder *)coder
{
if (self = [super init])
{
self.locationId = [coder decodeObjectForKey:@"locationId"];
self.companyName = [coder decodeObjectForKey:@"companyName"];
self.addressLine1 = [coder decodeObjectForKey:@"addressLine1"];
self.addressLine2 = [coder decodeObjectForKey:@"addressLine2"];
self.city = [coder decodeObjectForKey:@"city"];
self.postcode = [coder decodeObjectForKey:@"postcode"];
self.telephoneNumber = [coder decodeObjectForKey:@"telephoneNumber"];
self.description = [coder decodeObjectForKey:@"description"];
self.rating = [coder decodeObjectForKey:@"rating"];
self.priceGuide = [coder decodeObjectForKey:@"priceGuide"];
self.latitude = [coder decodeObjectForKey:@"latitude"];
self.longitude = [coder decodeObjectForKey:@"longitude"];
self.userLatitude = [coder decodeObjectForKey:@"userLatitude"];
self.userLongitude = [coder decodeObjectForKey:@"userLongitude"];
self.searchType = [coder decodeObjectForKey:@"searchType"];
self.searchId = [coder decodeObjectForKey:@"searchId"];
self.distance = [coder decodeObjectForKey:@"distance"];
self.applicationProviderId = [coder decodeObjectForKey:@"applicationProviderId"];
self.contentProviderId = [coder decodeObjectForKey:@"contentProviderId"];
}
return self; // this is missing in the example above
}
Я использую
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:results];
[prefs setObject:data forKey:@"lastResults"];
и
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"lastResults"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
objectArray = [[NSMutableArray alloc] init];
}
, и он прекрасно работает для меня.
С уважением,
Стефан